Silverlight3系列(五)数据绑定 Data Binding 2

      接着上面一篇,我们来讨论绑定集合等。

  

  首先看一下可以进行绑定集合的控件属性,暂时我就不翻译了,因为翻译不好,还不如读英文呢。

 

Name

Description

ItemsSource

 Points to the collection that has all the objects that will be shown in the list.

DisplayMemberPath

 Identifies the property that will be used to creat the display text for each item.

ItemTemplate

 Providers a data template that will be used to create the visual appearance of each item.This property acts as a far more powerful replacement for DisplayMemberPath.

ItemsPanel

 Providers a template that will be used to create the layout container that holds all the items in the list.

  这里你可能会想,什么类型的集合可以绑定到ItemsSource属性呢?告诉你,只需要实现IEnumerable就可以,但是,实现这个借口的集合是只读的。如果你想编辑这个集合,例如允许插入和删除,你需要更多的工作,后面我们会介绍。

 

  显示并且编辑集合项

  首先定义个数据库交互契约

   

ExpandedBlockStart.gif 代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ComponentModel;
using System.Runtime.Serialization;

namespace Domain.Entity
{
    [DataContract]
    public class Customer : INotifyPropertyChanged
    {
        private int _intCustomerId;
        private string _strCustomerName;
        private string _strCustomerCode;
        private CustomerType  _CustomerType;
        private int _intCustomerTypeId;

        [DataMember ]
        public virtual  int CustomerTypeId
        {
            get { return _intCustomerTypeId; }
            set { _intCustomerTypeId = value; }
        }

        [DataMember ]
        public virtual  CustomerType  CustomerType
        {
            get { return this._CustomerType; }
            set
            {

                this._CustomerType = value;
                OnPropertyChanged("CustomerType");
            }
        }

        [DataMember]
        public virtual int CustomerId
        {
            get { return this._intCustomerId; }
            set
            {
                this._intCustomerId = value;
                OnPropertyChanged("CustomerId");
            }
        }
        [DataMember]
        public virtual string CustomerName
        {
            get { return this._strCustomerName; }
            set
            {
                this._strCustomerName = value; OnPropertyChanged("CustomerName");
            }
        }
        [DataMember]
        public virtual string CustomerCode
        {
            get { return _strCustomerCode; }
            set
            {
                this._strCustomerCode = value;
                OnPropertyChanged("CustomerCode");
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}


 

 

  wcf定义接口

  

ExpandedBlockStart.gif 代码
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Domain.Entity;

namespace WcfService
{
    [ServiceContract]
    public interface IServiceCustomer
    {
        [OperationContract]
        Domain.Entity.Customer GetCustomer(int customerId);
        [OperationContract]
        IList
< Domain.Entity.Customer >  GetAll();
        [OperationContract]
        void Add(Domain.Entity.Customer customer);
        [OperationContract]
        string SayHello(SysUser sysUser);
    }
   
}

 

  实现这个接口

  

ExpandedBlockStart.gif 代码
using  System;
using  System.Linq;
using  System.Runtime.Serialization;
using  System.ServiceModel;
using  System.ServiceModel.Activation;
using  System.Collections.Generic;
using  System.Collections.ObjectModel;
using  System.Text;
using  System.Data.SqlClient;
using  System.Data;
using  Domain.Entity;
using  Common.Core;
using  Common.Data;
namespace  WcfService
{
    [AspNetCompatibilityRequirements(RequirementsMode 
=  AspNetCompatibilityRequirementsMode.Allowed)]
    
public   class  ServiceCustomer : IServiceCustomer
    {
        
private  CustomerDAO _customerDao;
        Common.Core.Utility.NHibernateUtility _NHUtility;
        MyValidator _myValidator;
        
public  ServiceCustomer()
        {
            _NHUtility 
=   new  Common.Core.Utility.NHibernateUtility();
            _customerDao 
=   new  CustomerDAO(_NHUtility.GetSession());
        }
        
//  Add more operations here and mark them with [OperationContract]

        
#region  IServiceCustomer Members
        
public  Domain.Entity.Customer GetCustomer(  int  customerId)
        {

            Domain.Entity.Customer objCustomer 
=   new  Domain.Entity.Customer();

            
return  _customerDao.GetCustomerById(customerId);
        }

        
#endregion

        
#region  IServiceCustomer Members


        
public  IList < Domain.Entity.Customer >  GetAll()
        {

            IList
< Domain.Entity.Customer >  cs  =  _customerDao.GetAll();
            
return  cs;
        }

        
#endregion

        
#region  IServiceCustomer Members


        
public   void  Add(Domain.Entity.Customer customer)
        {
            _customerDao.CreateCustomer(customer);

        }

        
#endregion

        
#region  IServiceCustomer Members


        
public   string  SayHello(SysUser sysUser)
        {
            _myValidator 
=  (MyValidator)OperationContext.Current.Host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator;

            
return   string .Format( " hello,{0},your password is {1}\n{2}{3} " , sysUser.UserName, sysUser.Password,
               
//  _myValidator.ToString(),_myValidator.ToString() );
                _myValidator.UserName ,_myValidator.Password );
        }

        
#endregion
    }
}

 

  Silverlight客户端前台代码

  

ExpandedBlockStart.gif 代码
< UserControl  xmlns:navigation ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"  
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"  
    xmlns:data
="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  x:Class ="Silverlight.sldbdemo"  
    Width
="400" >

    
< ScrollViewer >
        
< StackPanel >
            
< Button  x:Name ="btnGetCustomer"  Content ="获取一个用户信息"  Click ="btnGetCustomer_Click" ></ Button >
            
< Grid  x:Name ="LayoutRoot"  Background ="White" >
                
< Grid.ColumnDefinitions >
                    
< ColumnDefinition />
                    
< ColumnDefinition />
                
</ Grid.ColumnDefinitions >
                
< Grid.RowDefinitions >
                    
< RowDefinition  Height ="20" />
                    
< RowDefinition  Height ="20" />
                    
< RowDefinition  Height ="20" />
                    
< RowDefinition  Height ="20" />
                    
< RowDefinition  Height ="20" />
                    
< RowDefinition  Height ="20" />

                
</ Grid.RowDefinitions >
                
< TextBlock  x:Name ="LblCustomerId"  Grid.Column ="0"  Grid.Row ="0"  Text ="Customer Id" />
                
< TextBlock  x:Name ="TxtCustomerId"  Grid.Column ="1"  Grid.Row ="0"  Text ="{Binding CustomerId}" />
                
< TextBlock  x:Name ="LblCustomerCode"  Grid.Column ="0"  Grid.Row ="1"  Text ="Customer Code" />
                
< TextBlock  x:Name ="TxtCustomerCode"  Grid.Column ="1"  Grid.Row ="1"  Text ="{Binding CustomerCode}" />
                
< TextBlock  x:Name ="LblCustomerName"  Grid.Column ="0"  Grid.Row ="2"  Text ="用户名称" />
                
< TextBlock  x:Name ="TxtCustomerName"  Grid.Column ="1"  Grid.Row ="2"  Text ="{Binding CustomerName}" />


            
</ Grid >
            
< Button  x:Name ="btnGetAllCustomer"  Content ="获取全部用户信息"  Click ="btnGetAllCustomer_Click" ></ Button >
            
< Grid  x:Name ="customers"  Background ="Gray"  Grid.ColumnSpan ="2"  Grid.Column ="0"  Grid.Row ="3" >

                
< data:DataGrid  x:Name ="dataGrid"  CanUserResizeColumns ="true"  CanUserSortColumns ="True"
                           AutoGenerateColumns
="False"  ItemsSource ="{Binding}" >
                    
< data:DataGrid.Columns >
                        
< data:DataGridTextColumn  Header ="Id"  Binding ="{Binding CustomerId}" ></ data:DataGridTextColumn >
                        
< data:DataGridTextColumn  Header ="Code"  Binding ="{Binding CustomerCode}" ></ data:DataGridTextColumn >
                        
< data:DataGridTextColumn  Header ="Name"  Binding ="{Binding CustomerName}" ></ data:DataGridTextColumn >
                    
</ data:DataGrid.Columns >

                
</ data:DataGrid >

            
</ Grid >
            
< StackPanel  Grid.Column ="0"  Grid.ColumnSpan ="2"  Grid.Row ="4" >
                
< data:DataPager  x:Name ="tempPager"  DisplayMode ="FirstLastPreviousNextNumeric"  HorizontalAlignment ="Left"  VerticalAlignment ="Top"
                Source
="{Binding Path=ItemsSource,ElementName=dataGrid}"
               PageSize
="5"
                            
></ data:DataPager >
            
</ StackPanel >
            
< Grid  x:Name ="AddCustomer"  Background ="White"  Grid.Column ="0"  Grid.ColumnSpan ="2"  Grid.Row ="5"  Height ="97" >
                
< Grid.ColumnDefinitions  >
                    
< ColumnDefinition  Width ="0.5*" ></ ColumnDefinition >
                    
< ColumnDefinition  Width ="0.5*" ></ ColumnDefinition >
                
</ Grid.ColumnDefinitions >
                
< Grid.RowDefinitions  >
                    
< RowDefinition  Height ="0.247*"   ></ RowDefinition >
                    
< RowDefinition  Height ="0.247*"   ></ RowDefinition >
                    
< RowDefinition  Height ="0.247*"   ></ RowDefinition >
                    
< RowDefinition  Height ="0.258*"   ></ RowDefinition >
                
</ Grid.RowDefinitions >
                
< TextBlock  Text ="Customer Id"  Grid.Column ="0"  Grid.Row ="0" ></ TextBlock >
                
< TextBox  x:Name ="customerId"  Grid.Column ="1"  Grid.Row ="0" ></ TextBox >
                
< TextBlock  Text ="Custoemr Code"  Grid.Column ="0"  Grid.Row ="1" ></ TextBlock >
                
< TextBox  x:Name ="customerCode"  Grid.Column ="1"  Grid.Row ="1" ></ TextBox >
                
< TextBlock  Text ="Customer Name"  Grid.Column ="0"  Grid.Row ="2" ></ TextBlock >
                
< TextBox  x:Name ="customerName"  Grid.Column ="1"  Grid.Row ="2" ></ TextBox >
                
< Button  x:Name ="btnOk"  Grid.Column ="0"  Grid.Row ="3"  Height ="25"  Content ="添加用户Add Customer"  Click ="btnOk_Click" ></ Button >
            
</ Grid >
            
< Button  x:Name ="btnLoadData"  Click ="btnLoadData_Click"  Content ="加载数据" ></ Button >
            
< ListBox  x:Name ="lstCustomers" ></ ListBox >
        
</ StackPanel >
    
</ ScrollViewer >


</ UserControl >

 

  Silverlight客户端后台代码

 

ExpandedBlockStart.gif 代码
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  Silverlight.ServiceCustomer;
using  Domain.Entity;

namespace  Silverlight
{
    
public   partial   class  sldbdemo : UserControl
    {
        ServiceCustomerClient client;
        SysUser _sysUser;
        
private   int  _customerId  =   1 ;
        
public  sldbdemo()
        {
         
            InitializeComponent();
            client 
=   new  ServiceCustomerClient();
            client.ClientCredentials.UserName.UserName 
=   " adminstrator " ;
            client.ClientCredentials.UserName.Password 
=   " 123.com " ;
            _sysUser 
=   new  SysUser() { UserName  =   " swb " , Password  =   " swb "  };
          
       
           
            client.SayHelloAsync(_sysUser);
            client.SayHelloCompleted 
+=   new  EventHandler < SayHelloCompletedEventArgs > (client_SayHelloCompleted);
        }

        
void  client_SayHelloCompleted( object  sender, SayHelloCompletedEventArgs e)
        {
            
try
            {
                MessageBox.Show(e.Result);
            }
            
catch  (Exception ex)
            {
                MessageBox.Show(ex.Message 
+  ex.InnerException.Message);
            }
        }
        
protected   void  GetCustomerById( int  customerId)
        {
            
try
            {

                client.GetCustomerCompleted 
+=   new  EventHandler < GetCustomerCompletedEventArgs > (client_GetCustomerCompleted);
                client.GetCustomerAsync(customerId );
            }
            
catch  (Exception ex)
            {
                MessageBox.Show(ex.Message 
+  ex.InnerException.Message);
            }
        }

        
void  client_GetCustomerCompleted( object  sender, GetCustomerCompletedEventArgs e)
        {
          
//   Customer customer = new Customer() { CustomerId = 1, CustomerCode = "ss", CustomerName = "dddd" };
            
// LayoutRoot.DataContext = customer;
            LayoutRoot.DataContext  =  e.Result;
        }
        
protected   void  LoadCustomers()
        {
            
try
            {
                client.GetAllCompleted 
+=   new  EventHandler < GetAllCompletedEventArgs > (client_GetAllCompleted);
                client.GetAllAsync();
            }
            
catch  (Exception ex)
            {
                MessageBox.Show(ex.Message 
+  ex.InnerException.Message);
            }
        }
        
void  client_GetAllCompleted( object  sender, GetAllCompletedEventArgs e)
        {
            System.Windows.Data.PagedCollectionView page 
=   new  System.Windows.Data.PagedCollectionView(e.Result);
            tempPager.Source 
=  page;
            dataGrid.ItemsSource 
=  page;

        }

        
private   void  btnOk_Click( object  sender, RoutedEventArgs e)
        {
            
try
            {
                client.AddCompleted 
+=   new  EventHandler < System.ComponentModel.AsyncCompletedEventArgs > (client_AddCompleted);
                Domain.Entity.Customer customer 
=   new  Domain.Entity.Customer()
                {
                    CustomerId 
=   int .Parse(customerId.Text),
                    CustomerCode 
=  customerCode.Text,
                    CustomerName 
=  customerName.Text
                };
                client.AddAsync( customer);
            }
            
catch  (Exception ex)
            {
                MessageBox.Show(ex.Message 
+  ex.InnerException.Message);
            }
        }



        
void  client_AddCompleted( object  sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            
            LoadCustomers();
        }

        
private   void  btnLoadData_Click( object  sender, RoutedEventArgs e)
        {
            client.GetAllAsync();
            client.GetAllCompleted 
+= new  EventHandler < GetAllCompletedEventArgs > (client_GetAllCompleted1);
        }
        
void  client_GetAllCompleted1( object  sender, GetAllCompletedEventArgs e)
        {
            lstCustomers.ItemsSource 
=  e.Result;

        }

        
private   void  btnGetCustomer_Click( object  sender, RoutedEventArgs e)
        {
            GetCustomerById(_customerId);
        }

        
private   void  btnGetAllCustomer_Click( object  sender, RoutedEventArgs e)
        {
            LoadCustomers();
        }

    }
}

 

 

  效果图

  

  你会看到后面的listbox中,数据显示的全部都是Domain.Entity.Customer,没有显示成我们想要的某一栏的值,这就是因为在代码中我们使用了lstCustomers.ItemsSource = e.Result;第一种绑定集合的属性,这时候就需要第二种绑定集合的属性 DisplayMemberPath="CustomerName"登场了。

  其实实现上面的效果,你可以有三条途径:

  1)设置控件的DisplayMemberPath属性为一个对象的属性名称,例如:DisplayMemberPath="CustomerName",效果如下图

  2)重写对象的ToString()方法,提供一些有用的信息,设置可以显示几个属性,因为默认绑定使用的就是对象的tostring方法

  

 

public   override   string  ToString()
        {
            
return   string  .Format ( " 用户代码:{0} | 用户姓名:{1} " ,CustomerCode,CustomerName );
        }

 

  属性就不用修改了,还是<ListBox x:Name="lstCustomers" ></ListBox>,效果如下图

  3)提供一个数据模板,这样你可以显示任何排列好的对象属性值,后面将会讲到这种做法。

 

  到这里你可能又需要两外一个功能了,就是点击一个list中的item,在下面显示一下详细信息。你可以响应listbox的SelectionChanged事件,在事件代码中写上

     

 

  private   void  lstCustomers_SelectionChanged( object  sender, SelectionChangedEventArgs e)
        {
            gridCustomerDetails.DataContext 
=  lstCustomers.SelectedItem;
        }

 

  前台设置为

 

ExpandedBlockStart.gif 代码
  < ListBox  x:Name ="lstCustomers"  SelectionChanged ="lstCustomers_SelectionChanged" ></ ListBox >
            
< Grid  x:Name ="gridCustomerDetails"  Background ="White" >
                
< Grid.ColumnDefinitions >
                    
< ColumnDefinition />
                    
< ColumnDefinition />
                
</ Grid.ColumnDefinitions >
                
< Grid.RowDefinitions >
                    
< RowDefinition  Height ="20" />
                    
< RowDefinition  Height ="20" />
                    
< RowDefinition  Height ="20" />
                    
< RowDefinition  Height ="20" />
                    
< RowDefinition  Height ="20" />
                    
< RowDefinition  Height ="20" />

                
</ Grid.RowDefinitions >
                
< TextBlock  x:Name ="LblCustomerIdd"  Grid.Column ="0"  Grid.Row ="0"  Text ="Customer Id" />
                
< TextBlock  x:Name ="TxtCustomerIdd"  Grid.Column ="1"  Grid.Row ="0"  Text ="{Binding CustomerId}" />
                
< TextBlock  x:Name ="LblCustomerCoded"  Grid.Column ="0"  Grid.Row ="1"  Text ="Customer Code" />
                
< TextBlock  x:Name ="TxtCustomerCoded"  Grid.Column ="1"  Grid.Row ="1"  Text ="{Binding CustomerCode}" />
                
< TextBlock  x:Name ="LblCustomerNamed"  Grid.Column ="0"  Grid.Row ="2"  Text ="用户名称" />
                
< TextBlock  x:Name ="TxtCustomerNamed"  Grid.Column ="1"  Grid.Row ="2"  Text ="{Binding CustomerName}" />


            
</ Grid >
  

 

  效果如下图

  

  

  插入和删除集合中的项

  你通过服务接口获取的数据集合可能是各种各样的,array、list等,但是在客户端他们的存储类型都是 System.Collections.ObjectModel.ObservableCollection,当你返回一个集合的时候,自动翻译类型。

  这种设计是因为客户端不知道服务器会返回什么类型的集合,Silverlight假设使用 System.Collections.ObjectModel.ObservableCollection类型是安全的,因为 System.Collections.ObjectModel.ObservableCollection相对array、dictionary来说都有更多的功能。

  在sl前台加上一个button

   <Button x:Name="btnDelCustomer" Content="删除一个用户" Click="btnDelCustomer_Click"></Button>

  然后再后台写上

  

ExpandedBlockStart.gif 代码
  private   void  btnDelCustomer_Click( object  sender, RoutedEventArgs e)
        {
            System.Collections.ObjectModel.ObservableCollection
< Customer >  customers  =  (System.Collections.ObjectModel.ObservableCollection < Customer > )lstCustomers.ItemsSource ;
            customers .Remove ((Customer )lstCustomers.SelectedItem );
        }

 

  在页面上就会看到效果,这只是从集合中删除,并没有从后端数据库删除,你加载一下的话,数据还是在的。如果要实现真正的数据操作,还是要利用wcf的服务来实现数据库的操作。

  LINQ是.NET 3.5中的一个新型的数据查询方式,就是对对象集合的查询,更加面向对象的查询。它的查询结果是实现了IEnumerable<T>接口的,所以使用LINQ查询的结果也是可以绑定到ItemsSource的。

  

ExpandedBlockStart.gif 代码
IEnumerable < Customer >  maths  =  from c  in  customers
                                          
where  c.CustomerName = =   " dd "
                                          select c;
            lstCustomers.ItemsSource 
=  maths;

 

 

 

  不像list或者ObserverableCollection,IEnumerable<T>接口没有提供添加或者删除方法。如果你需要的话,可以使用接口的toarray和tolist方法转化为有操作方法的集合,如果更加需要的话,还可以进一步搞成ObserverableCollection集合。

  List<Customer > list = maths.ToList<Customer>();

  接下来我们要实现的这么一种效果,就先下列出来所有的用户类型,然后选中类型之后,再显示当前类型的全部用户姓名,选中用户姓名之后,再显示用户详细信息。

  我们要添加一个用户类型的定义,在wcf中要添加一个获取全部类型的接口。

  

ExpandedBlockStart.gif 代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ComponentModel;
using System.Runtime.Serialization;
using Iesi.Collections.Generic;

namespace Domain.Entity
{
    [DataContract]
    public class CustomerType : INotifyPropertyChanged
    {
        private string _strCustomerTypeName;
        private int _intCustomerTypeId;
        private ISet<Customer> _customers;
        [DataMember ]
        public virtual  int CustomerTypeId
        {
            get { return this._intCustomerTypeId; }
            set
            {

                this._intCustomerTypeId = value;
                OnPropertyChanged("CustomerTypeId");
            }
        }

        [DataMember]
        public virtual string CustomerTypeName
        {
            get { return this._strCustomerTypeName; }
            set
            {
                this._strCustomerTypeName = value; OnPropertyChanged("CustomerTypeName");
            }
        }
        [DataMember]
        public virtual  ISet <Customer> Customers
        {
            get { return this._customers; }
            set
            {
                this._customers = value;
                OnPropertyChanged("Customers");
            }
        }
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

 

 

 

  

ExpandedBlockStart.gif 代码
  #region  IServiceCustomer Members

        
public  IList < Customer >  GetCustomerByTypeId( int  typeId)
        {
            
return  _customerDao.GetCustomerByTypeId(typeId);
        }

       
public   IList < CustomerType >  GetAllCustomerType()
        {
           
return   _customerTypeDao.GetAll();
        }

        
#endregion

    插入一个有用的连接,Silverlight 的 .NET Framework 类库,里面是Silverlight客户端可以使用的.NET类库。

        稳扎稳打Silverlight(22) - 2.0通信之调用WCF服务, 对传输信息做加密       

 

  

      代码可以在http://silverlightwcf.codeplex.com/下载。

  

转载于:https://www.cnblogs.com/virusswb/archive/2010/01/27/1657551.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值