今天我们讨论的是Silverlight3中的数据绑定,内容来自 《Pro Silverlight3 in C#》的读后感。
数据绑定提供了一种,从对象中获取信息,然后显示在你的应用程序的界面上,同时不需要写冗长的代码就可以完成所有的工作的方式。通常情况下,富客户端提供两种绑定方式,不仅可以从兑现获取数据,显示到界面上,也可以将界面的数据传回给对象。
Silverlight是不允许客户端直接使用ADO.NET直接连接数据库,进行数据库操作的。只能通过代理的方式操作数据库,通过第三方,例如:webservice、wcf、ado.net data service、ric service等服务性的方式。(文/virus)
1、绑定到数据对象
例如现在又一个Customer的实体对象
数据对象
- [DataContract]
- public class Customer
- {
- private int _intCustomerId;
- private string _strCustomerName;
- private string _strCustomerCode;
- [DataMember]
- public virtual int CustomerId
- {
- get { return this._intCustomerId; }
- set { this._intCustomerId = value; }
- }
- [DataMember]
- public virtual string CustomerName
- {
- get { return this._strCustomerName; }
- set { this._strCustomerName = value; }
- }
- [DataMember]
- public virtual string CustomerCode
- {
- get { return _strCustomerCode; }
- set { this._strCustomerCode = value; }
- }
- }
想要达到下图的一种效果
就需要下面这样的代码,在页面中可以用 Text="{Binding CustomerId}"来实现。
前台页面
- <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>
后台代码
绑定到对象
- void client_GetCustomerCompleted(object sender, GetCustomerCompletedEventArgs e)
- {
- Customer customer = new Customer() { CustomerId = 1, CustomerCode = "ss", CustomerName = "dddd" };
- LayoutRoot.DataContext = customer;
- }
提供一篇文章,供大家参考:Using Static Resource in Silverlight 3 Application
首先要在类代码中存在一个资源对象,
代码
- namespace Silverlight
- {
- public class Users
- {
- public string Firstname { get; set; }
- public string Lastname { get; set; }
- }
- public partial class DataBindingDemo : UserControl
- {
- public DataBindingDemo()
- {
- InitializeComponent();
- }
- }
- }
- <UserControl x:Class="Silverlight.DataBindingDemo"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:local="clr-namespace:Silverlight"
- Width="400" Height="300">
- <UserControl.Resources>
- <local:Users x:Key="SingleUser" Firstname="virus" Lastname="ssss"></local:Users>
- </UserControl.Resources>
- <Grid x:Name="LayoutRoot" Background="White">
- <TextBox Text="{Binding Path=Firstname,Source={StaticResource SingleUser}}"></TextBox>
- </Grid>
- </UserControl>
- <UserControl.Resources>
- <local:Users x:Key="SingleUser" Firstname="virus" Lastname="ssss"></local:Users>
- </UserControl.Resources>
- <TextBox Text="{Binding Path=Firstname,Source={StaticResource SingleUser}}"></TextBox>
3、可编辑的双向绑定
到这里你可能想要知道,如果我在界面上修改一个值,会发生什么呢?例如你修改了界面上面的文本框的值,文本框的值绑定了一个对象的属性,在内存中的对象属性会改变吗?
实际上,内存中的对象属性没有任何变化,因为Silverlight默认使用单向绑定。
System.Windows.Data.BindingMode枚举量中定义了全部的绑定类型,如下表:
Name |
Description |
OneWay 单向绑定 |
当对象属性改变的时候,绑定对象就会改变 |
TwoWay 双向绑定 |
当源对象属性改变的时候,绑定对象会改变;反过来,绑定对象的改变也会影响源对象属性的改变。 |
OneTime 一次性绑定 |
绑定对象在第一次初始化的时候显示对象的属性,后面不会随着对象属性的改变而改变,这种适用于你确定对象的属性几乎不会改变的情况下。 |
- <TextBox Text="{Binding Firstname, Mode=TwoWay}"></TextBox>
使用了双向绑定之后,焦点一离开控件之后就会触发内存对象的改变,但是有的时候我们想精确控制,而不是等焦点移除的时候,例如:输入框在用户输入的同时就进行,而不是等用户焦点移出输入框,你可以在代码中调用 BindingExpression.UpdateSource();
代码
- private void txtFirstname_TextChanged(object sender, TextChangedEventArgs e)
- {
- BindingExpression expression = txtFirstname.GetBindingExpression(TextBox.TextProperty);
- expression.UpdateSource();
- }
代码
- <TextBox x:Name="txtFirstname"
- Text="{Binding Path=Firstname,Source={StaticResource SingleUser}, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
- TextChanged="txtFirstname_TextChanged"></TextBox>
4、数据验证 Validation
数据验证将在下一篇中重点讲解。先提供一个实例代码下载:DataValidation
验证的话,就需要Silverlight客户端和wcf服务端共享类库,共享实体类,因为服务端的实体类虽然被序列化到客户端,但是只能序列化状态信息,就是成员,方法之类的不会序列化的,而且就算序列化过来,也没有什么用,运行环境context都不一样了,没有什么意思。所以可能会用到客户端和服务端共享类库,可以参考下面的文章。
Silverlight客户端和WCF服务器端共享类库
5、绑定到一个数据服务
更复杂的数据绑定中,数据可能是从外部服务获取的。这里的外部服务使用wcf来提供,下面的代码假定你已经了解wcf,如果不了解的可以看老徐的博客或者google一些资料来看。数据库操作部分使用NHibernate 2.1.2完成。
首先定义数据交互契约
实体代码
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.ServiceModel;
- using System.ComponentModel;
- using System.Runtime.Serialization;
- namespace Domain.Server
- {
- [DataContract]
- public class Customer : INotifyPropertyChanged
- {
- private int _intCustomerId;
- private string _strCustomerName;
- private string _strCustomerCode;
- [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服务代码
代码
- 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.Server;
- using Common.Core;
- using Common.Data;
- namespace WcfService
- {
- 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());
- //string name = OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name;
- }
- // Add more operations here and mark them with [OperationContract]
- public Domain.Server.Customer GetCustomer(int customerId)
- {
- Domain.Server.Customer objCustomer = new Domain.Server.Customer();
- return _customerDao.GetCustomerById(customerId);
- }
- }
- }
Silverlight的前台代码
代码
代码
|