摘要:本文通过一个实例帮助读者了解WPF基本的绑定操作,包括绑定到实体、集合、格式化、校验等任务。
要求:阅读本文需要对WPF有个基本的认识,熟悉.NET开发。
作者:谈少民
编写日期:2006-11-24
摘要:本文通过一个实例帮助读者了解WPF基本的绑定操作,包括绑定到实体、集合、格式化、校验等任务。
要求:阅读本文需要对WPF有个基本的认识,熟悉.NET开发。
开始
首先下载本文章的例子(如果你安装了Vista SDK应该已经包含了这个例子),他是MS为WPF创建的一个学习例子,地址是:
http://download.microsoft.com/download/9/d/0/9d0d2396-3219-4d4c-a7dd-b26c8ad400b7/WPFSamples.exe
安装后,你可以在以下目录下找到这个例子:
C:\Program Files\Microsoft SDKs\Microsoft SDKs\Windows\v6.0\Samples\ConnectedData\DataBindingLab
OK,首先我们直接运行这个例子,运行的样子如下:
如果点击 Add Product按钮,将出现下面的画面:
数据源
在.NET 2.0中,可以直接使用和常见的数据源包括:DataSet和BindingSource,事实上,还是比较宽松的,单个对象的属性都可以绑定,如果要做到同步,包含 PropertyName Changed事件或者符合System.ComponentModel.INotifyPropertyChanged接口就可以了,在集合绑定方面只要符合System.Collections.ICollection接口就可以,问题在如果要实现跟踪,就只有System.ComponentModel.IBindingList可以选择了,这个接口设计的有些大了。
.NET 3.0中,对集合更新的跟踪做了简单的定义:System.Collections.Specialized.INotifyCollectionChanged,而且还有一个System.Windows.IWeakEventListener接口,看名字就知道了。
现成的绑定源我找到有System.Windows.Data.CollectionViewSource和System.Collections.ObjectModel.ObservableCollection<T>,好像选择挺多的,有点晕了。
CollectionViewSource是个很Cool的组件,他可以让你分组或者排序,非常的方便。
绑定
先拿添加产品那个窗口为例子,因为他足够简单,只需要绑定到普通对象上,下面是绑定到Description的文本框:
< TextBox Name ="DescriptionEntryForm" Text ="{Binding Path=Description, UpdateSourceTrigger=PropertyChanged}" />
意思是Text属性使用绑定功能,使用Binding对象处理,其中绑定到对象上的属性为Description,更新模式是PropertyChanged模式。
上面的描述也可以用另外一种语法:
< TextBox Name ="StartPriceEntryForm" > < TextBox .Text > < Binding Path ="StartPrice" UpdateSourceTrigger ="PropertyChanged" > </ TextBox.Text > </ TextBox >
道理一样的。
因为绑定指定的是Path而不是PropertyName,所以你也可以写成Owner.Name:
< TextBlock Name ="OwnersNameDTKey" Text ="{Binding Path=Owner.Name}" />
如果你足够有想象力的话,集合也可以绑定,象这样:
Path=(Validation.Errors)[0].ErrorContent
现在指定了绑定到哪个属性,那如何指定数据源呢?控件上(实际上是FrameworkElement)包含一个重要的属性DataContext,意思是数据上下文(废话),你的绑定数据都来源这里,我感觉他象是内置的BindingSource控件。
在初始化时,AddProduct窗口包含下面的代码:
private void OnInit( object sender, RoutedEventArgs e) { this .DataContext = new AuctionItem( " Type your description here " , ProductCategory.DVDs, 1 , DateTime.Now, ((DataBindingLabApp)Application.Current).CurrentUser, SpecialFeatures.None); }
这就等于更新了数据源的内容。
你也可以使用命名的数据源,他作为一种资源出现:
< Window .Resources > < CollectionViewSource Source ="{Binding Source={x:Static Application.Current}, Path=AuctionItems}" x:Key ="listingDataView" /> </ Window.Resources >
他使用了CollectionViewSource作为数据源控件,内部跟踪Application.Current.AuctionItems的数据,在这个例子中AuctionItems是一个ObservableCollection<AuctionItem>集合类实例。
在使用时,指定他就是了:
< ListBox Name ="Master" ItemsSource ="{Binding Source={StaticResource listingDataView}}" > </ ListBox >
数据转化
在这个例子中,包含了一个日期和字符串互相转化的例子,第一步工作是编写一个转化器类:
[ValueConversion( typeof (DateTime), typeof (String))] public class DateConverter : IValueConverter { public object Convert( object value, Type targetType, object parameter, CultureInfo culture) { DateTime date = (DateTime)value; return date.ToShortDateString(); } public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture) { string strValue = value.ToString(); DateTime resultDateTime; if (DateTime.TryParse(strValue, out resultDateTime)) { return resultDateTime; } return value; } }
这个转化类必须符合IValueConverter接口,并且在类上部标记ValueConversion标记,指明是DateTime和String之间的转化,这个功能是.NET 3.0新增的功能,位于System.Data.Windows命名空间。
要应用这个转化工具还真的挺绕的,首先需要将其定义成一个命名资源,这个申明放在Application中:
< Application .Resources > < src:DateConverter x:Key ="dateConverter" />
然后,你就可以在绑定的文本框中使用他了,例如在添加产品的Start Date中:
< TextBox Name ="StartDateEntryForm" Grid.Row ="3" Grid.Column ="1" Validation.ErrorTemplate ="{StaticResource validationTemplate}" Style ="{StaticResource textStyleTextBox}" Margin ="8,5,0,5" > < TextBox .Text > < Binding Path ="StartDate" UpdateSourceTrigger ="PropertyChanged" Converter ="{StaticResource dateConverter}" > < Binding .ValidationRules > < src:FutureDateRule /> </ Binding.ValidationRules > </ Binding > </ TextBox.Text > </ TextBox >
注意绑定申明中的Converter属性的指定。
另外,还有一种IMultiValueConverter,
数据校验
数据校验是另外一个重要的功能,在.NET 2.0中,数据源只需要符合System.ComponentModel.IDataErrorInfo接口就可以了,DataSet就是一个例子,在.NET 3.0中使用了ValidationRule抽象类处理校验工作,他将被依附在Binding中。
class FutureDateRule : ValidationRule { public override ValidationResult Validate( object value, CultureInfo cultureInfo) { DateTime date; try { date = DateTime.Parse(value.ToString()); } catch (FormatException) { return new ValidationResult( false , " Value is not a valid date. " ); } if (DateTime.Now.Date > date) { return new ValidationResult( false , " Please enter a date in the future. " ); } else { return ValidationResult.ValidResult; } } }
还是比较简单的,没有什么可解释的,一样,这个校验器需要具体使用到哪个Binding中,
< Binding Path ="StartDate" UpdateSourceTrigger ="PropertyChanged" Converter ="{StaticResource dateConverter}" > < Binding .ValidationRules > < src:FutureDateRule /> </ Binding.ValidationRules > </ Binding >
你可能注意到你是可以指定多个校验器。
参考资料:
Windows Presentation Foundation 数据绑定:第一部分
Windows Presentation Foundation 数据绑定:第二部分
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构