WPF and Silverlight学习笔记(二十四):数据源提供器(DataProvider) -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

在WPF中系统提供了两个数据源提供器(DataProvider):对象数据源提供器 (ObjectDataProvider)和XML数据源提供器(XmlDataProvider),

WPF and Silverlight学习笔记(二十四):数据源提供器(DataProvider)

。其作用类似 于ASP.Net数据源(DataSource)中的对象数据源(ObjectDataSource)和Xml数 据源(XmlDataSource)。其继承结构如下:

ObjectDataProvider用于处理由方法返回值所产生的数据源,其应用 非常广泛,通常多层应用程序通常在界面上使用ObjectDataProvider处理由组件 层所产生的数据。在本节中我们主要处理ObjectDataProvider,对于 XmlDataProvider感兴趣的朋友可以参考MSDN。

一、组件端定义

例如:定义一个类库项目,在其中定义一个ProductInfo类、CategoryInfo类, 用来封装Northwind数据库中的Products表及Categories表中的数据。定义 NorthwindDataSet,包含Product、Category两个DataTable。定义DataControl 类,处理对Northwind数据库的操作,返回相应的封装后的类型或集合作为界面 显示的数据源。

1、ProductInfo类和CategoryInfo类

1:  namespace WPF_24_Library
2: {
3:   /// 


4:   /// 封装产品表的信息
5:   /// 

6:   public class ProductInfo
7:    {
8:     public int ProductID
9:     {
10:        set; get;
11:     }
12:     public  string ProductName
13:     {
14:       set;  get;
15:     }
16:     public decimal  UnitPrice
17:     {
18:       set; get;
19:     }
20:     public int CategoryID
21:      {
22:       set; get;
23:     }
24:   }
25: }

1: using  System.Collections.Generic;
2:
3: namespace  WPF_24_Library
4: {
5:   /// 
6:    /// 封装类别表的信息
7:   /// 

8:    public class CategoryInfo
9:   {
10:      public CategoryInfo()
11:     {
12:        Products = new List();
13:     }
14:
15:     public int CategoryID
16:     {
17:       set; get;
18:     }
19:      public string CategoryName
20:     {
21:        set; get;
22:     }
23:
24:     /// 
25:     /// 封装该类别的所有产品
26:      /// 

27:     public  List Products
28:     {
29:        private set; get;
30:     }
31:   }
32:  }

2、类型化DataSet

此类型化DataSet由Visual Studio IDE生成:

3、DataControl类

DataControl类用来处理所有的数据库的操 作,其功能分为以下几个部分:

基于返回集合的方法GetAllProductInfo

基于返回集合并带参数的方法GetProductInfoByCategoryID

基 于返回带主从关联数据的集合的方法GetAllCategoriesWithProducts

基 于返回带主从关联数据的类型化DataSet的方法GetNorthwindDataSet

1: using System.Collections.Generic;
2: using  System.Data;
3: using System.Data.SqlClient;
4:
5:  namespace WPF_24_Library
6: {
7:   public static  class DataControl
8:   {
9:     // 连接字符串
10:     private const string CONNECTION_STRING =
11:        @"Server=.;Integrated  Security=SSPI;Database=Northwind";
12:
13:     //  所使用的各存储过程的名称
14:     private const string  SQL_GETALLPRODUCTINFO = "sp_GetAllProductInfo";
15:      private const string SQL_GETPRODUCTINFOBYCATEGORYID =  "sp_GetProductInfoByCategoryID";
16:     private  const string SQL_GETALLCATEGORIES =  "sp_GetAllCategories";
17:
18:     /// 


19:     /// 获取所有的产品
20:      /// 

21:     /// 
22:     public static  List GetAllProductInfo()
23:     {
24:       SqlCommand command = new SqlCommand();
25:        command.CommandType = CommandType.StoredProcedure;
26:       command.CommandText = SQL_GETALLPRODUCTINFO;
27:
28:       List result =  GetProducts(command);
29:
30:       return  result;
31:     }
32:
33:     /// 
34:     /// 根据产品类别获取此类别的产品
35:     /// 

36:     /// 
37:     ///  
38:     public static  List GetProductInfoByCategoryID(int categoryID)
39:     {
40:       SqlCommand command = new  SqlCommand();
41:       command.CommandType =  CommandType.StoredProcedure;
42:       command.CommandText  = SQL_GETPRODUCTINFOBYCATEGORYID;
43:
44:        command.Parameters.Add("@categoryID", SqlDbType.Int).Value  = categoryID;
45:
46:        List result = GetProducts(command);
47:
48:       return result;
49:     }
50:
51:     /// 
52:     /// 封装产品数 据
53:     /// 

54:     /// 
55:      /// 
56:     private  static List GetProducts(SqlCommand command)
57:     {
58:       SqlConnection connection =  new SqlConnection();
59:        connection.ConnectionString = CONNECTION_STRING;
60:        connection.Open();
61:
62:        command.Connection = connection;
63:
64:        SqlDataReader dataReader = command.ExecuteReader();
65:        List result = new  List();
66:       while  (dataReader.Read())
67:       {
68:          int id = dataReader.GetInt32(0);
69:         string  name = dataReader.GetString(1);
70:         int  categoryID = dataReader.GetInt32(2);
71:          decimal unitprice = dataReader.GetDecimal(3);
72:
73:          ProductInfo info = new ProductInfo()
74:          {
75:           ProductID = id,
76:            ProductName = name,
77:            CategoryID = categoryID,
78:           UnitPrice  = unitprice
79:         };
80:          result.Add(info);
81:       }
82:        dataReader.Close();
83:       connection.Close();
84:
85:       return result;
86:     }
87:
88:     /// 
89:     /// 获 取所有的类别及该类别的产品
90:     /// 

91:     /// 
92:      public static List  GetAllCategoriesWithProducts()
93:     {
94:        SqlConnection connection = new SqlConnection();
95:        connection.ConnectionString = CONNECTION_STRING;
96:        connection.Open();
97:
98:        SqlCommand command = new SqlCommand();
99:        command.CommandType = CommandType.StoredProcedure;
100:        command.CommandText = SQL_GETALLCATEGORIES;
101:
102:       SqlDataReader dataReader =  command.ExecuteReader();
103:        List result = new List ();
104:       while (dataReader.Read())
105:        {
106:         int id = dataReader.GetInt32 (0);
107:         string name = dataReader.GetString (1);
108:
109:         CategoryInfo info = new  CategoryInfo()
110:         {
111:            CategoryID = id,
112:           CategoryName  = name,
113:         };
114:          result.Add(info);
115:       }
116:        dataReader.Close();
117:       connection.Close();
118:
119:       foreach (CategoryInfo info in  result)
120:       {
121:          info.Products.AddRange(
122:            GetProductInfoByCategoryID(info.CategoryID));
123:        }
124:
125:       return result;
126:      }
127:
128:     /// 
129:      /// 获取封装所有类别及产品的DataSet
130:     /// 

131:     /// 
132:     public static  NorthwindDataSet GetNorthwindDataSet()
133:     {
134:        SqlDataAdapter categoryAdapter = new SqlDataAdapter (
135:         SQL_GETALLCATEGORIES,  CONNECTION_STRING);
136:        categoryAdapter.SelectCommand.CommandType =  CommandType.StoredProcedure;
137:
138:        SqlDataAdapter productAdapter = new SqlDataAdapter(
139:          SQL_GETALLPRODUCTINFO, CONNECTION_STRING);
140:        productAdapter.SelectCommand.CommandType =  CommandType.StoredProcedure;
141:
142:        NorthwindDataSet result = new NorthwindDataSet();
143:
144:       categoryAdapter.Fill(result.Categories);
145:        productAdapter.Fill(result.Products);
146:
147:       return result;
148:     }
149:    }
150: }

二、基本ObjectDataProvider操作

( 将上部分类库项目引入WPF应用程序项目中)

使用ObjectDataProvider时 需提供以下几个部分:

x:Key:此Provider对应的资源的名称,将在界面 某组件的DataContext引用,以作为数据源

ObjectType:包含返回数据 源的方法的类,其语法上是这样的:ObjectType=”{x:Type 类名}” ,此外还需要引用相应的命名空间

MethodName:返回数据源的方法的方 法名

例如:将GetAllProductInfo方法返回的List 泛型集合做为数据源,绑定到ListBox上:

1:  2:    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation& quot;
3:    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4:   xmlns:lib="clr- namespace:WPF_24_Library;assembly=WPF_24_Library"
5:    Title="ObjectDataProvider Demo 1" Height="300"  Width="300">
6:   
7:     
14:     
15:   

16:   
17:     
18:       
19:       
20:     

21:       22:            HorizontalAlignment="Center"  VerticalAlignment="Center" >
23:       
24:       
25:        
26:      
27:      28:         DataContext=" {StaticResource productInfoByCategoryIDSource}"
29:          ItemsSource="{Binding}"
30:          DisplayMemberPath="ProductName"
31:          SelectedValuePath="ProductID" />
32:   

33: 

此外,可以通过代 码更改参数的值:

1: private void Button_Click(object  sender, RoutedEventArgs e)
2: {
3:   int categoryID  = int.Parse(txtCategoryID.Text);
4:
5:    ObjectDataProvider provider =
6:     (ObjectDataProvider) (this.FindResource("productInfoByCategoryIDSource"));
7:   provider.MethodParameters[0] = categoryID;
8: }

三、带主从关联数据的数据显示

所谓的“主从数据”所指的例如上图中,左侧为所有的类 别,右侧为当前选中类别的所有产品,其实现的XAML如下:

1:  2:    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation& quot;
3:    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4:   xmlns:lib="clr- namespace:WPF_24_Library;assembly=WPF_24_Library"
5:    Title="WinObjectDataProviderDemo4" Height="300"  Width="500">
6:   
7:      8:                bjectType="{x:Type lib:DataControl}"
9:                MethodName="GetAllCategoriesWithProducts"  />
10:   

11:   
12:      
13:       
14:        
15:     

16:      17:          ItemsSource="{Binding}"
18:          DisplayMemberPath="CategoryName"
19:          SelectedValuePath="CategoryID"
20:          SelectedIndex="0"
21:          IsSynchronizedWithCurrentItem="True" />
22:       23:          ItemsSource="{Binding Path=Products}"
24:          DisplayMemberPath="ProductName"
25:          SelectedValuePath="ProductID" />
26:   

27: 

需要注意的是,默 认情况下,ListBox不会同步数据源当前项的变更改,需要使用第21行的代码, 以实现点击左侧的ListBox的某一项,同时更改右侧该类别的产品,

电脑资料

WPF and Silverlight学习笔记(二十四):数据源提供器(DataProvider)》(https://www.unjs.com)。

四、 使用DataSet做为数据源

将DataSet做为数据源时大体与集合相同,但要 注意,DataContext对应的数据源类型是一个DataSet时,Binding时需使用Path 指定控件对应绑定到的DataTable。

1:  2:    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation& quot;
3:    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4:   xmlns:lib="clr- namespace:WPF_24_Library;assembly=WPF_24_Library"
5:    Title="WinObjectDataProviderDemo3" Height="300"  Width="500">
6:   
7:      8:                bjectType="{x:Type lib:DataControl}"
9:                MethodName="GetNorthwindDataSet" />
10:   

11:   
12:     
13:       
14:        
15:     

16:      17:          ItemsSource="{Binding Path=Categories}"
18:         DisplayMemberPath="CategoryName"
19:         SelectedValuePath="CategoryID"
20:          SelectionChanged="ListBox_SelectionChanged"
21:          IsSynchronizedWithCurrentItem="True"
22:          x:Name="lst"/>
23:      24:          ItemsSource="{Binding Path=Categories/FK_Products_Categories} "
25:          DisplayMemberPath="ProductName"
26:          SelectedValuePath="ProductID" />
27:   
28: 

另外还需要注意的 是第24行,绑定主从数据时,子数据绑定的Path为“主表名/关系名 ”。

应用程序执行的结果如下:

附:代码所使用的存储过程:

1: use Northwind
2: GO
3:
4: Create Proc sp_GetAllProductInfo
5:  As
6:   Select ProductID,ProductName,CategoryID,UnitPrice
7:   From Products
8:
9: GO
10:
11: Create  Proc sp_GetProductInfoByCategoryID
12:   @categoryID  int
13: As
14:   if @categoryID is null or  @categoryID=0
15:     Select  ProductID,ProductName,CategoryID,UnitPrice
16:     From  Products
17:   else
18:     Select  ProductID,ProductName,CategoryID,UnitPrice
19:     From  Products
20:     Where CategoryID=@categoryID
21:
22: GO
23:
24: Create Proc sp_GetAllCategories
25: As
26:   Select CategoryID,CategoryName
27:    From Categories

最新文章