在之前写的一篇文章中,提到当在WCF中创建一个类,SL中引用该WCF服务后该类会变成 XXClient的样子,当初初学(现在也是,不过要好一点点),对Wcf服务和Sl之间的关系看得比较片面。其实在Wcf中创建ServiceContract契约标注的类的时候才会在Sl中变成XXClient的形式的类,而还有一种创建Wcf类的契约指定DataContract,这个契约的用途主要是制订一个类的数据结构,提供给引用其服务的客户端共享类型。
在通过wcf将一个数据集合传递给Sl的时候,我们会发现,异步完成事件的参数e的Result获得的数据集合是System.Collections.ObjectModel.ObservableCollection泛型的,如果,我们的wcf中返回的是一个DataView,那么在Sl中绑定这个结果是会出错的,因为Sl中并没提供DataView类,那怎么办呢?
于是,我们就会想自己写一个数据集合类来返回给SL,那么SL那边是不是也要写个相同的类来接收?Sl的数据绑定是可以通过绑定类的属性来实现的,但是,wcf上定义的类如何让Sl知道就是和他自己定义的类是一样的??
我们是写的一样的,可是SL不这么认为,就算一模一样,他们依然是两个类,不可共用的,也不存在继承关系。
于是,在创建wcf就得用DataContract定义一个类型出来,这样定义之后,sl上就可以共享这个类了,这个服务被sl引用后,这个类就跟sl自己的一样,sl和wcf签订了一个契约,我们都用这个类吧。这时,问题就解决了。
我们获取一个数据集合,比如说DataView ,然后将这个集合中的每一项的每一个字段作为属性赋值给那个DataContract指定的类的实例,有多少项就得创建多少个这个类的实例,然后创建一个List泛型来存储这一堆的实例。之后我们就将List泛型返回给SL,Sl获得这个List集合后,一看,泛型指定的是DataContract定义的类,正是wcf契订的那个类,sl引用了这个服务,当然也就共享了这个类,这个类也是sl自己的,好,sl虽然获得的依然是System.Collections.ObjectModel.ObservableCollection泛型,但是泛型里的类型是它所了解的那个类,那么就可以直接将结果绑定到类似DataGrid的控件上了。
DataContract标注这个类的时候,其要勇于共享的字段或属性需要用DataMember标注,就像ServiceContract标注的类里的要共享的方法需要用OperationContract标注一样。
很困了,随便写,改天有空整理,白话讲出来也就这个意思。
另外,Sl中 DataGrid绑定数据时,实际上是绑定一个由N个类实例组合的集合,该集合的每一项就是一个类实例,DataGird绑定这个集合的时候,每一行是一项,每一行的每一列是该项的类的每一个属性。也就是说,一行就是一个类实例,一列就是一个实例的一个属性
太困了
贴点代码:
wcf
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Text;
using System.Data;
namespace QiWeiXian
{
[ServiceContract(Namespace = "Qiweixian.com")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class WebWcf
{
[OperationContract]
public List<BookItem> GetBookList()
{
DataView dv = new DataView();
DataClass dc = new DataClass();
dv = dc.GetBooks(DateTime.Now.Date, DateTime.Now.Date.AddDays(1));
dv.Sort = "ID Desc";
List<BookItem> list = new List<BookItem>();
BookItem bi;
for (int i = 0; i < dv.Count; i++)
{
bi = new BookItem();
bi.ID = (int)dv[i]["ID"];
bi.Name = dv[i]["Name"].ToString();
bi.Peoples = (int)dv[i]["Peoples"];
bi.Phone = dv[i]["Phone"].ToString();
bi.Remark = dv[i]["Remark"].ToString();
bi.Remark2 = dv[i]["Remark2"].ToString();
bi.Status = (int)dv[i]["Status"];
bi.AddTime = (DateTime)dv[i]["AddTime"];
bi.BookTime = (DateTime)dv[i]["BookTime"];
list.Add(bi);
}
return list;
}
}
[DataContract]
public class BookItem
{
[DataMember]
public int ID;
[DataMember]
public string Name;
[DataMember]
public DateTime BookTime;
[DataMember]
public int Peoples;
[DataMember]
public DateTime AddTime;
[DataMember]
public string Phone;
[DataMember]
public string Remark;
[DataMember]
public string Remark2;
[DataMember]
public int Status;
}
}
sl cs
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.Windows.Data;
namespace BookOnline
{
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
BookListBind();
}
public void BookListBind()
{
WebWcf.WebWcfClient wc = new BookOnline.WebWcf.WebWcfClient();
wc.GetBookListAsync();
wc.GetBookListCompleted += new EventHandler<BookOnline.WebWcf.GetBookListCompletedEventArgs>(wc_GetBookListCompleted);
}
void wc_GetBookListCompleted(object sender, BookOnline.WebWcf.GetBookListCompletedEventArgs e)
{
System.Collections.ObjectModel.ObservableCollection<BookOnline.WebWcf.BookItem> members = e.Result;
BookList.ItemsSource = members;
}
}
}