Создание приложения веб-чата на Silverlight 2 - Web.config и WCF

ОГЛАВЛЕНИЕ

Web.config и WCF

При добавлении службы WCF к веб-приложению несколько строк кода автоматически было добавлено к файлу Web.config в теге system.ServiceModel. Хотя все тут стандартно, надо отметить информацию связывания в строке 126. По умолчанию она будет запрограммирована как "wsHttpBinding"; надо сменить ее на basicHttpBinding, как показано и выделено ниже:

109     <system.serviceModel>
110         <behaviors>
111             <endpointBehaviors>
112                 <behavior name="Silverlight2Chat.Web.Service1AspNetAjaxBehavior">
113                     <enableWebScript />
114                 </behavior>
115             </endpointBehaviors>
116             <serviceBehaviors>
117                 <behavior name="Silverlight2Chat.Web.LinqChatServiceBehavior">
118                     <serviceMetadata httpGetEnabled="true" />
119                     <serviceDebug includeExceptionDetailInFaults="false" />
120                 </behavior>
121             </serviceBehaviors>
122         </behaviors>
123         <services>
124             <service behaviorConfiguration="Silverlight2Chat.Web.LinqChatServiceBehavior"
125                 name="Silverlight2Chat.Web.LinqChatService">
126                 <endpoint address="" binding="basicHttpBinding"
                              contract="Silverlight2Chat.Web.ILinqChatService">
127                     <identity>
128                         <dns value="localhost" />
129                     </identity>
130                 </endpoint>
131                 <endpoint address="mex" binding="mexHttpBinding"
                                      contract="IMetadataExchange" />
132             </service>
133         </services>
134     </system.serviceModel>

Запоминание информации и переход от одного пользовательского управляющего элемента XAML к другому

Как сказано ранее, Silverlight – клиентская технология. Оттого нельзя использовать объекты сессии для запоминания чего-то и нельзя использовать известную команду Response.Redirect для перехода к следующей странице/пользовательскому управляющему элементу XAML. Хотя можно разместить один файл XAML в веб-форме ASP.NET, Silverlight не задуман так. Надо переключаться или переходить от одного файла XAML к другому, размещенному в одной и той же веб-форме ASP.NET или странице HTML. По умолчанию при создании приложения Silverlight генерируется файл Page.xaml, также являющийся стандартным пользовательским управляющим элементом XAML, используемым или размещаемым при запуске приложения Silverlight. Пользовательский управляющий элемент Page был удален в силу ненужности. Зато были добавлены два пользовательских управляющих элемента: Login.xaml и Chatroom.xaml. Будет совершаться перемещение туда-сюда от Login.xaml к Chatroom.xaml и наоборот с помощью пользовательского управляющего элемента App.xaml.

App.xaml - пользовательский управляющий элемент уровня приложения Silverlight. В нем устанавливается, какой пользовательский управляющий элемент будет показываться или вызываться первым в приложении. В нем запоминаются идентификатор пользователя и имя пользователя. Он работает как Web.config, где хранятся ресурсы уровня приложения.

1.    Установка Login.xaml в качестве стандартного пользовательского управляющего элемента XAML: В событии Application_Startup из App.xaml измените "Page()" на "Login()", как показано в строке 32.

28     private void Application_Startup(object sender, StartupEventArgs e)
29     {
30         // начать со страницы входа
31         this.RootVisual = rootGrid;
32         rootGrid.Children.Add(new Login());
33     }

2.    Метод RedirectTo, созданный в пользовательском управляющем элементе App.xaml, осуществляет переход от пользовательского управляющего элемента Login.xaml к Chatroom.xaml. Этот метод принимает пользовательский управляющий элемент, куда надо перенаправиться. Здесь удаляется текущий пользовательский управляющий элемент и добавляется пользовательский управляющий элемент, который надо показать пользователю. Этот метод вызывается из XAML входа, после того как пользователь войдет в раздел чата, и из XAML раздела чата при выходе пользователя. Код показан ниже:

69     public void RedirectTo(UserControl usercontrol)
70     {
71         App app = (App)Application.Current;
72         app.rootGrid.Children.Clear();
73         app.rootGrid.Children.Add(usercontrol);
74     }

Чтобы перенаправить пользователя из Login.xaml в Chatroom.xaml, из пользовательского управляющего элемента Login.xaml делается следующее:

81     App app = (App)Application.Current;
82     app.UserID = userID;
83     app.UserName = TxtUserName.Text;
84     app.RedirectTo(new Chatroom());

3.    Чтобы помнить значение из одного пользовательского управляющего элемента XAML в другом, в пользовательском управляющем элементе App.xaml создается открытое свойство для каждого из значений, которое надо помнить.

76     public int UserID { get; set; }
77
78     public string UserName { get; set; }
79
80     public DateTime TimeUserJoined { get; set; }

После создания этих свойств им присваиваются значения, которые надо запомнить из Login.xaml или Chatroom.xaml. Ниже показан код из Login.xaml.

81     App app = (App)Application.Current;
82     app.UserID = userID;

Пользовательский интерфейс Chatroom.xaml

Надо отметить несколько вещей о пользовательском интерфейсе раздела чата, и все они выделены ниже. Сообщения и список пользователей используют управляющие элементы StackPanel, но привязки данных различаются. Список пользователей использует более простой тег DataTemplate, привязывающий все имена пользователей в виде гиперссылок. Сообщения привязываются в отделенном коде, потому что сообщения должны показывать более сложный набор управляющих элементов. Как видно на снимке раздела чата, сообщения разноцветные; имена и сообщения рядом с ними не должны быть одинаковых цветов. Подробнее это рассмотрено далее.

Задано событие KeyDown для текстового поля сообщения (куда пользователь вводит сообщения), так что можно проверить, нажал ли пользователь клавишу "ввод" клавиатуры. Когда пользователь нажимает клавишу «ввод», отправляется сообщение. Подробнее это рассмотрено далее.

<UserControl x:Class="Silverlight2Chat.Chatroom"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="600" Height="340">
    <Grid x:Name="LayoutRoot" Background="White"
              ShowGridLines="False" Loaded="LayoutRoot_Loaded">
        <Grid.RowDefinitions>
            <RowDefinition Height="10" />       <!-- отступ -->
            <RowDefinition Height="38" />       <!-- заголовок -->
            <RowDefinition Height="10" />       <!-- отступ -->
            <RowDefinition Height="*" />        <!-- сообщения, список пользователей -->
            <RowDefinition Height="10" />       <!-- отступ -->      
            <RowDefinition Height="26" />       <!— текстовое поле сообщения, кнопка отправки -->
            <RowDefinition Height="10" />       <!-- отступ -->
        </Grid.RowDefinitions>
 
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="10" />     <!-- отступ -->
            <ColumnDefinition Width="*" />      <!-- сообщения, текстовое поле сообщения -->
            <ColumnDefinition Width="10" />     <!-- отступ -->
            <ColumnDefinition Width="120" />    <!-- список пользователей, кнопка отправки-->
            <ColumnDefinition Width="10" />     <!-- отступ -->
        </Grid.ColumnDefinitions>
 
        <TextBlock Text="Silverlight 2 Chat" Grid.Row="1"
          Grid.Column="1" FontSize="22" Foreground="Navy" />
 
        <StackPanel Orientation="Vertical" Grid.Row="1" Grid.Column="3">
            <TextBlock x:Name="TxtbLoggedInUser" FontSize="10"
               Foreground="Navy" FontWeight="Bold" HorizontalAlignment="Center" />
            <Button x:Name="BtnLogOut" Content="Log Out"
              FontSize="10" Click="BtnLogOut_Click" />
        </StackPanel>
 
        <ScrollViewer x:Name="SvwrMessages" Grid.Row="3" Grid.Column="1"
                      HorizontalScrollBarVisibility="Hidden"
                      VerticalScrollBarVisibility="Visible" BorderThickness="2">
            <StackPanel x:Name="SpnlMessages" Orientation="Vertical" />
        </ScrollViewer>

        <ScrollViewer x:Name="SvwrUserList" Grid.Row="3" Grid.Column="3"
                      HorizontalScrollBarVisibility="Auto"
                      VerticalScrollBarVisibility="Auto" BorderThickness="2">
            <StackPanel x:Name="SpnlUserList" Orientation="Vertical">
                <ItemsControl x:Name="ItmcUserList">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <HyperlinkButton Content="{Binding UserName}" />
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>  
            </StackPanel>
        </ScrollViewer>
 
        <StackPanel Orientation="Horizontal" Grid.Row="5" Grid.Column="1" >
            <TextBox x:Name="TxtMessage" TextWrapping="Wrap"
                 KeyDown="TxtMessage_KeyDown" 
                 ScrollViewer.VerticalScrollBarVisibility="Visible"
                 ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                 Width="360"
                 BorderThickness="2" Margin="0,0,10,0"/> 
 
            <ComboBox x:Name="CbxFontColor" Width="80">
                <ComboBoxItem Content="Black" Foreground="White"
                   Background="Black" IsSelected="True" />
                <ComboBoxItem Content="Red" Foreground="White" Background="Red" />
                <ComboBoxItem Content="Blue" Foreground="White" Background="Blue" />
            </ComboBox>
        </StackPanel>
 
        <Button x:Name="BtnSend" Content="Send"
          Grid.Row="5" Grid.Column="3" Click="BtnSend_Click" />
    </Grid>
</UserControl>