65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (12投票s)

2010年5月20日

Ms-PL

2分钟阅读

viewsIcon

81542

downloadIcon

990

一个简单的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.xamlMainPage.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方法的简单示例

© . All rights reserved.