Silverlight 4 简单示例(使用 oData 和 RX 扩展)





5.00/5 (12投票s)
一个简单的Silverlight应用程序,它使用RX扩展与OData服务进行通信。
引言
这是之前博客文章的第二部分(http://openlightgroup.net/Blog/tabid/58/EntryId/98/OData-Simplified.aspx),我们查看了一个简单的OData示例。这次,我们将创建一个简单的Silverlight应用程序来与OData服务通信。
请注意,对于本教程,您还需要下载并安装RX扩展:http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx,以及Silverlight工具包:http://silverlight.codeplex.com。
与上一个教程一样,我们不会使用数据库,而只是程序化创建的简单集合。这将使您能够只看到OData部分。
首先,从此链接底部的zip文件中打开Visual Studio 2010(或更高版本)中的项目。
选择添加,然后新建项目...
创建一个新的Silverlight应用程序。
添加服务引用。
单击发现。
创建一个名为wsSampleCustomerData的引用。
接下来,在您的Silverlight项目中添加对以下程序集的引用:
System.CoreEx
System.Observable
System.Reactive
在Silverlight项目中,删除MainPage.xaml。
在Expression Blend 4(或更高版本)中打开项目。
在Expression Blend中,选择文件,然后新建项...
选择带有ViewModel的用户控件模板,并创建一个名为MainPage.xaml的文件。
它将创建ViewModel页面(MainPage.xaml和MainPage.xaml.cs,以及一个已经连接好的MainPageModel.cs ViewModel页面)。
创建一个名为Model的文件夹和一个名为Model.cs的类。
用以下代码替换所有代码
using System;
using System.Linq;
using System.Collections.Generic;
using SilverlightODataSample.wsSampleCustomerData;
using System.Data.Services.Client;
namespace SilverlightODataSample
{
public class Model
{
#region GetCustomers
public static IObservable < IEvent < LoadCompletedEventArgs> >
GetCustomers(int intPage)
{
// Create a URI that points to the OData Service
Uri objUri = new Uri(GetBaseAddress(), UriKind.RelativeOrAbsolute);
// Set up oData service call
SampleDataSource SDS = new SampleDataSource(objUri);
// Construct a Query
var query = (from SampleCustomerData in SDS.SampleCustomerData
where SampleCustomerData.CustomerNotes.Contains("3")
select SampleCustomerData).Skip(intPage).Take(10);
// Set up a DataServiceCollection to hold the results
DataServiceCollection< CustomerRecord > CustomerRecords =
new DataServiceCollection< CustomerRecord >();
// Set up a Rx Observable (in a variable called observable)
// that will contain the results of
// the "LoadCompleted" event that CustomerRecords will fire
// When LoadAsync(query) is fired in the following statement
IObservable< IEvent < LoadCompletedEventArgs> > observable =
Observable.FromEvent< LoadCompletedEventArgs >(CustomerRecords,
"LoadCompleted");
// Execute the LoadAsync on CustomerRecords passing
// the query that was constructed earlier
CustomerRecords.LoadAsync(query);
// Return observable
return observable;
}
#endregion
#region GetBaseAddress
private static string GetBaseAddress()
{
// This gets the address of the webservice by
// getting the AbsoluteUri and then stripping out the
// name of the .xap file
string strXapFile = @"/ClientBin/SilverlightODataSample.xap";
string strBaseWebAddress =
App.Current.Host.Source.AbsoluteUri.Replace(strXapFile, "");
return string.Format(@"{0}/{1}", strBaseWebAddress, @"Service.svc");
}
#endregion
}
}
打开MainPageModel.cs并将所有代码替换为以下代码
using System;
using System.ComponentModel;
using System.Collections.ObjectModel;
using SilverlightODataSample.wsSampleCustomerData;
using System.Data.Services.Client;
namespace SilverlightODataSample
{
public class MainPageModel : INotifyPropertyChanged
{
public MainPageModel()
{
// When the Control loads
// Get the Customers
GetCustomers();
}
#region GetCustomers
private void GetCustomers()
{
// Call the Model to get the Customers
// Passing in 0 to get the first page
// Paging could easily be done here
// You could also pass in other criteria
Model.GetCustomers(0).Subscribe(p = >
{
// Check for an error in the Service
if (p.EventArgs.Error == null)
{
// loop thru each item in the
// DataServiceCollection< CustomerRecord >
// Collection
foreach (CustomerRecord Customer in
(DataServiceCollection< CustomerRecord >)p.Sender)
{
// Add to the Customer to the colCustomerRecord
// Collection so the View can bind to it
colCustomerRecord.Add(Customer);
}
}
});
}
#endregion
#region CustomerRecord
// The View will bind to this collection and automatically be notified if
// The collection changes. The Designer can bind any UI element that
// can hold a collection
private ObservableCollection< CustomerRecord > _colCustomerRecord
= new ObservableCollection< CustomerRecord >();
public ObservableCollection< CustomerRecord > colCustomerRecord
{
get { return _colCustomerRecord; }
private set
{
if (colCustomerRecord == value)
{
return;
}
_colCustomerRecord = value;
this.NotifyPropertyChanged("colCustomerRecord");
}
}
#endregion
#region INotifyPropertyChanged
// This is a supporting method to raise a notification for any
// Element that is subscribed to a Property that implements
// NotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
}
获取一个DataGrid
并将其拖放到设计界面上。
将其加宽以填充页面。
单击数据选项卡,以便查看数据上下文。
将colCustomerRecord
集合拖放到DataGrid
上。
生成并运行项目。
OData和RX扩展非常令人印象深刻
- 使用RX扩展是因为它将OData服务调用与ViewModel解耦。这允许模型中的方法被多个ViewModel轻松调用。
- 我们只获取结果的第一页,但我们可以通过将页码传递给方法来轻松实现分页。
- 我们也只创建了一个简单的查询。我们可以轻松地创建OData服务的更复杂查询。
安全
有关保护OData方法的信息,请参阅:保护WCF数据服务OData方法的简单示例。