Работа вне браузера и с web-сервисами
Подключение к базе данных с помощью классов Windows Communication Foundation
Для создания приложения, имеющего доступ к базе данных с помощью технологии Windows Communication Foundation необходимо выполнить шаги, показанные на рис. 3.6, рис. 3.7, рис. 3.8, рис. 3.9, рис. 3.10 и рис. 3.11. Создав модель данных на этих этапах можно приступить к созданию веб-сервиса для того, чтобы информация была доступна приложению Silverlight, работающему со стороны клиента. В данном разделе используется модель WCF/SOAP и шаблон Silverlight-Enabled WCF Service. Щелкнем правой кнопкой мыши по веб-проекту BusinessApplication1.Web и выберем Add… New Item, выбрав Silverlight-Enabled WCF Service. Новый сервис будет называться ProductServiceWPF.svc. Если открыть ProductServiceWPF.svc.cs, можно найти метод-пустышку DoWork, который переименуем в GetProducts и изменим так, чтобы он получал список товаров Product из базы данных AdventureWorks.
Код изменим следующим образом:
namespace BusinessApplication1.Web { [ServiceContract(Namespace = "")] [AspNetCompatibilityRequirements (RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class ProductServiceWPF { [OperationContract] public List<Product> GetProducts() { AdventureWorksLT2008Entities1 dataEntity = new AdventureWorksLT2008Entities1(); return dataEntity.Product.Where (prod => prod.ListPrice > 3000).ToList(); } } }
Первая строка списка GetProducts() создает экземпляр dataEntity, который мы определили ранее. Вторая строка запрашивает экземпляр данных об объектах Product, но поскольку их слишком много, то добавим оператор where, использующий выражение prod => prod.ListPrice > 3000 для того, чтобы уменьшить число возвращаемых элементов. Чтобы привести возвращаемую сущность к списку List, вызываем свойство ToList(), конвертируя результат в List<Product>.
Теперь переходим в проект BusinessApplication1 и на странице MainPage.xaml добавляем элемент управления DataGrid по имени dataGrid1:
<UserControl xmlns:data="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls.Data" x:Class="SilverlightApplication7.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"> <Grid x:Name="LayoutRoot"> <data:DataGrid x:Name="dataGrid1" /> </Grid> </UserControl>
Теперь необходимо привязать данные из веб-сервиса к данным табличной сетки. Это делается в Page.xaml.cs. Первым шагом будет добавление к этому проекту ссылки на веб-сервис. Для этого после щелчка правой кнопкой мыши по ServiceReferences и в диалоговом окне Add Service Reference по Discover увидим, созданный ранее веб-сервис (ProductServiceWPF), который появится в списке. Пространство имен останется ServiceReference1.
Добавить ссылку на сервис нужно в MainPage.xaml.cs.
ServiceReference1.ProductServiceWPFClient clnt = new SilverlightApplication7.ServiceReference1. ProductServiceWPFClient();
Хотя приложение Silverlight запускается в браузере, мы не можем осуществлять вызовы методов напрямую (нельзя блокировать браузер), нам скорее необходимо осуществлять асинхронные вызовы. Intellisense не только предлагает нам альтернативу в виде асинхронных вызовов, но и не предлагает нам синхронные методы, которые были созданы!
В общем код, после добавления обработчика событий и привязки источника данных к веб-сервису выглядит следующим образом:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.ComponentModel; using System.Threading; namespace BusinessApplication1 { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); ServiceReference1.ProductServiceWPFClient clnt = new SilverlightApplication7.ServiceReference1. ProductServiceWPFClient(); clnt.GetProductsCompleted += new EventHandler<SilverlightApplication7. ServiceReference1.GetProductsCompletedEventArgs> (clnt_GetProductsCompleted); clnt.GetProductsAsync(); } void clnt_GetProductsCompleted(object sender, SilverlightApplication7.ServiceReference1. GetProductsCompletedEventArgs e) { this.dataGrid1.ItemsSource = e.Result; } } }
Результат выполнения будет выглядеть, как показано на рис. 3.19.
Когда проект будет скомпилирован, информация будет извлечена из базы данных, и результат будет ограничиваться лямбда-выражением, ограничивающим цену выше 3000. Он будет доступен посредством веб-сервиса и привязан к элементу управления DataGrid.
Далее рассмотрим, что можно сделать с таблицами, чтобы гибко отображать данные.
Работа с таблицами
При работе с таблицами DataGrid по умолчанию можно осуществлять сортировку по значению одного поля. Одно нажатие на заголовке поля дает сортировку по возрастанию, два - по убыванию (рис. 3.20). Можно также изменить ширину колонки.
Можно ограничить количество выводимых полей, например тремя:
<data:DataGrid x:Name="dataGrid1" AutoGenerateColumns="False" > <data:DataGrid.Columns> <data:DataGridTextColumn x:Name="ListPrice" Header="ListPrice" Binding="{Binding ListPrice}"/> <data:DataGridTextColumn x:Name="ModifiedDate" Header="ModifiedDate" Binding="{Binding ModifiedDate}"/> <data:DataGridTextColumn x:Name="Name" Header="Name" Binding="{Binding Name}"/> </data:DataGrid.Columns> </data:DataGrid>
Остальные сервисы, такие как paging, grouping, filtering делаются методами .NET и не рассматриваются в контексте Silverlight framework.