zoukankan      html  css  js  c++  java
  • 数据绑定

    1. 数据绑定(Binding)一般配置

    常用的绑定的目标(Dependency Object & associated Dependency Property,目标单元): 
    内容控件目标:object ContentControl.Content 
    集合控件目标:IEnumerable ItemsControl.ItemSource

    绑定器: 
    Binding ( : BindingBase : MarkupExtension ) 
    Binding binding = new Binding(); 
    binding.ElementName = "WPF控件名称";  / binding.Source = …; 
    binding.Path = new System.Windows.PropertyPath("路径串");

    绑定到源(Object & its Property): 
    代码动态绑定:BindingExtensionBase FrameworkElement.SetBinding(DependencyProperty dp,  BindingBase binding)  (dp = ContentControl.ContentProperty, ItemsControl.ItemsSourceProperty, …) 
                  
    XAML举例:<Label Content=”{Binding … Path=…}”…> ,  <ListBox ItemsSource=”{Binding … Path=…}"> … 
    ({Binding}中单独出现Path时,“Path=”可以省略)

    取消绑定:BindingOperations.ClearBinding(this.Label1, ContentControl.ContentProperty);

    使用DataContext: 
    设置某个单元的FrameworkElement.DataContext属性,为其子单元提供默认的绑定源(Source,ElementName,RelativeSource未设置的Binding),可通过代码和XAML设置。

    设置绑定模式: 
    Default - 采用目标使用的默认方式 
    OneTime - 仅在程序启动或数据源引用或context变动时候更新,但源本身的值发生变化不触发更新 
    OneWay - 仅目标因源而改变(实验中发现,有的时候目标因用户修改,例如TextBox,可能不会再接受源的更改) 
    OneWayToSource - 仅源因目标而改变 
    TwoWay - 双向变化 
    源更新: 
    在上述使用向源反馈更新模式时,设置Binding.UpdateSourceTrigger决定更新的频率: 
    Explicit - 仅在BindingExpression.UpdateSource()时更新,BindingExpression通过这个形式获取:textBox.GettBindingExpression(TextBox.TextProperty); 
    LostFocus - 在包含目标的单元失去焦点时更新; 
    PropertyChanged - 每当目标发生变化时; 
    Default - 根据目标的特性的默认值。

    2. 绑定到Object

    用Binding.Source而不是Binding.ElementName,Binding.Path通常忽略。 
    常用的如画刷设置,以下示例静态对象引用格式: 
    <Button Background=”{Binding Source={x:Static SystemColors.WindowColor}}” …

    另一种应用是绑定到逻辑资源: 
    在资源中定义某个类型的一个资源<名空间别名:类名 x:Key="对象名称"> 
    绑定:Content=”{Binding Source={StaticResource 对象名称}, Path=对象属性}"… 
    其中名空间别名定义: xmlns:别名="clr-namespace:工程代码中的名空间名称[;assembly=库名]"

    3. 绑定到WPF控件

    ElementName设为组件名字符串;Path设为表示值的组件的变量。

    4. 绑定到相对位置

    Binding中的源采用RelativeSource。 
    相对搜索模式: 
    FindAncestor模式从上级搜索源,用AncestorType指定源类型,AncestorLevel指定搜索个数; 
    TemplatedParent模式用于指向当前模板应用的对象; 
    Self通常完成自身两个属性的绑定; 
    PreviousData绑定到数据列表中的前一个数据项。

    5. 绑定到List

    ItemsControl.ItemsSource设置到实现IEnumerable的对象,格式:{Binding Source=主表  Path=xxx},Path用于指定在多层表中指定中间路径,用'.'分隔,CurrentItem指某级的当前项。 
    ItemsControl.IsSynchronizedWithCurrentItem将选定项和CurrentItem同步。 
    ItemsControl.DisplayMemberPath用于指定作为最终显示的字段的属性。 
    ItemsControl.ItemTemplate用于指定数据模板(Data Template)。内容显示由ItemsControls.DisplayMemberPath或ItemsControl.ItemTemplate内部定义(见“数据模板”)两者之一决定。

    内容控件的Content绑定到列表项的某个属性,则需将Path设置到该属性(多层表用'.'分隔,CurrentItem指某级当前项)

    使用ICollectionView检视列表数据(命名空间System.ComponentModel) 
    ICollectionView   o-- 
    DispatcherObject   -- CollectionView – ListCollectionView 
                                         - BindingListCollectionView 
    ICollectionView icv = CollectionViewSource.GetDefaultView(myCollection); 
    (如果是IBindingList则返回IBindingListCollectionView,是IList则返回IListCollectionView) 
    icv可以用于浏览,icv.CurrentItem指向当前项(目前未发现能实现多级表)

    6. 绑定到ADO.NET

    用{Binding Path=xx/yy/zz (Source=tt)}模式。 
    Data Set:首先调用Adapters的Fill将DataSet对象中的DataTable,DataContext可以设到DataSet或其下辖DataTable,在Path中相应调整即可。 
    多层级目标:无当前项指标(CurrentItem),只需表示层级路径即可。 
    关联数据表:将父表设IsSynchronizedWithCurrentItem="True",关联属性表现在Path中,将目标字段表现在DisplayMemberPath,这样关联即显示在界面上。关联设置在VS中导入的XSD文件上进行,设置父子表和相应的关键栏和外部关键键栏。

    7. 绑定到ObjectDataProvider

    将WPF单元内容绑定到一个对象的方法的返回值,主要需要设置ObjectDataProvider.ObjectType到对象类型,ObjectDataProvider.MethodName到方法名称,MethodParameters,ConstructorParameters属性用来指定方法参数和对象构造函数参数。在XAML中格式: 
    在资源(xxx.Resources)中定义: 
    <ObjectDataProvider x:Key=”myDataProvider” ObjectType={x:Type 名空间:类名}" MethodName=”…” /> 
    引用: {Binding Source={StaticResource myDataProvider}} 
    此种方式始终只读,即不允许改变数据源。

    8. 绑定到XML

    在资源(xxx.Resources)中定义: 
    <XmlDataProvider x:Key=”…” Source=”xxx.xml”/> 
    或者: 
    <XmlDataProvider x:Key=”…”> 
    <x:XData> 
       直接嵌入XML数据 
    </x:XData> 
    </XmlDataProvider> 
    引用时类似7将Source指向资源。

    在多层级列表模式下,DataContext=”{Binding …}" 用于定位。一般在全局区(如Grid),DataContext的Binding设置Source,并用XPath过滤掉不需要考虑的高层级。 
    在下一级,DataContext的Binding设置Path=CurrentItem,如果是二级以上,必须设ElementName以指向上一列表控件,而Path=SelectedItem,这样将上一级的选定项设为本级的Context。而ItemsSource的Binding则用XPath进行过滤修正,而最终显示项则取决于ItemsControls.DisplayMemberPath或ItemsControl.ItemTemplate两者之一。对XML中的属性内容在路径中用@propName格式。以下举例说明ItemTemplate的使用: 
    <ListBox.ItemTemplate> 
      <DataTemplate> 
        <TextBlock Text=”{Binding XPath=@propName}” />  
      </DataTemplate> 
    </ListBox.ItemTemplate>

    9. 数据模板(Data Templates)

    上一节已经涉及了数据模板的使用。数据模板用于定制数据的显示。 
    列表控件:设置在ItemsControl.ItemTemplate(DataTemplate类型)上。ItemTemplate顾名思义,对应一个列表项的显示,因此可以通过适当组织将一个列表项对应多个数据字段。 
    内容控件:设置在ContentControl.ContentTemlate。 
    数据模板的类型均为DataTemplate,显然内容也就定义在<DataTemplate></DataTemplate>中,是一个DependencyObject。涉及元素项内容通常用{Binding Path=…}(XML用XPath)绑定。 
    在资源中定义数据模板:类似一般资源,在DataTemplate上标记x:Key,在使用的时候用ItemTemplate="{StaticResource xxx}"引用。

    10. 数据排序(Sorting)

    1. 用CollectionViewSource.GetDefaultView(…)先获取一个ICollectionView(使用命名空间System.ComponentModel) 
    2. 在SortDescriptionCollection ICollectionView.SortDescriptions上调Add方法,添加new SortDescription("字段名称", ListSortDirection.Ascending(升序)) 
    3. 可以继续添加SortDescription,根据添加先后确定排序优先级。

    自定义排序: 
    对于默认生成ListCollectionView(即实现IList,但非IBindingList,如ObservableCollection),通过设置IComparer ListCollectionView.CustomSort属性可以应用自定义排序。IComparer需要实现的方法是:int Compare(object x, object y)

    在XAML中直接定义CollectionViewSource: 
    1. <CollectionViewSource x:Key=’somekey’ (这个Source定义成资源) 
                                         Source=“{Binding xxx}” (绑定到源列表,类似GetDefaultView的参数,XML可设XPath) 
    2. 随后可以定义<CollectionViewSource.SortDescriptions>或以下的<CollectionViewSource.GroupDescriptions>中的内容,类似于上述Add方法。 
    3. 后续依赖于源列表和这个基于CollectionViewSource的分组或排序定义的单元可以直接将Binding的源定义到上面的Key。

    11. 数据编组(Grouping)

    编组即排序加区分。 
    1. …获取一个ICollectionView 
    2. 在ObservableCollection<GroupDescription> ICollectionView.GroupDescriptions上调Add方法,添加new PropertyGroupDescription("字段名"[, CustomGrouper]),其中PropertyGroupDescription 继承自GroupDescription,自定义编组需CustomGrouper实现IValueConverter接口。 
    3. 设置列表控件的组的显示特性ItemsControl.GroupStyle(如<ListBox.GroupStyle>)。GroupStyle有五个主要属性,常用: 
    HeaderTemplate,它是一个控制组表头的显示的DataTemplate,其{Binding Path=xxx},实际绑定到PropertyGroupDescription构造函数第一个参数指定的属性(在某些情况下可忽略为{Binding}); 
    Panel,它是一个设置列表元素布局的模板,ItemsPanelTemplate类型,注意这个Panel是以Group为单位进行布局的,而不是直接针对Item; 
    ContainerStyle,Style类型,用于指定每个具体的编组元素(TargetType为GroupItem)的样式。有关Template使用详见后续章节。

    DispatcherObject - FrameworkTemplate – DataTemplate 
                                         - ItemsPanelTemplate 
    自定义编组: 
    IValueConverter需要实现object Convert(object value, Type targetType, object parameter, Sytem.Globalization.CultureInfo culture)和同参数的ConvertBack函数,在编组中ConvertBack函数不被调用。Convert方法完成PropertyGroupDescription指定的数据转换,转换输出的内容被作为最终分组的依据,通常可以进行字符串格式化操作和一些映射等(详见13节)。

    12. 数据过滤(Filtering)

    根据Predicate委托类型:bool Predigate<T>(T obj),实现一个过滤器,设置ICollectionView.Filter属性到这个方法上,只有通过过滤(返回true)的才会包含进来并显示。

    在使用ADO.NET或使用BindingListCollectionView时,则不能用上述过滤方法。而要用BindingListCollectionView.CustomFilter字符串,通常形如"字段名=='值'"。具体格式同DataColumn.Expression,非WPF关注内容,参见相关文档。

    13. 数据转换

    如11所述,IValueConverer数据转换可用于编组,需要实现的方法也已介绍。 
    通常定义实现IValueConverter的类之前需要标志[ValueConversion(typeof(输入类型), typeof(输出类型)]修饰,一般不需要实现ConvertBack方法的实际功能。 
    在XAML中使用转换器: 
    1. 用xmlns引用必要的名空间。 
    2. 在资源如<Window.Resources>中实例化一个转换器(用x:Key标识)。 
    3. 在用到数据绑定Binding的地方,设置Binding的Converter属性引用资源中这个转换器。

    字符串格式化(详见相关文档)。常用: 
    数值到货币:num.ToString("C"); (这个转换基于当前线程的文化信息) 
    日期格式化:d-短日期格式,D-长日期格式,f-长日期短时间格式,F-长日期长时间格式,G-一般格式,M-日月,s-ISO标准格式

    提取对象。例如: 
    从URI字符串提取图像。

    个性化列表项: 
    例如设置转换器将输入日期转换到一个画刷,将转换器设置到列表项DataTemplate中单元(如Label)的Foreground的Binding上,就实现不同日期的不同颜色显示。

    转换器的本地化: 
    Convert方法中有一个文化信息参数culture,据此可以对转换过程做适当的处理,例如调用相应的翻译器等。

    多参数转换: 
    实现接口IMultiValueConverter,相应的转换方法: 
    object Convert(object[] values, Type targetType, 后同); 
    object[] ConvertBack(object value, Type[] targetTypes, 后同); 
    多参数转换也是在XAML的资源中实例化转换器,然后在MuliBinding中使用: 
    <MultiBinding Converter="资源"> 
      <Binding Path=xxx1 /> 
      <Binding Path=xxx2 /> 
    </MultiBinding>

    14. 数据验证(Validation)

    数据验证在界面上指示数据的有效性。 
    它通过Collection<ValidationRule> Binding.ValidationRules包含的验证规则实现,验证过程根据定义依次执行: 
    <Binding.ValidationRules> 
      <ns:ValidationRule派生类1/> 
      <ns:ValidationRule派生类2/> 
      .. 
    </Binding.VaidationRules>

    派生类必须重载:ValidationResult Validate(object value, CultureInfo ci);  
    ValidationResult构造:ValidationResult(bool isvalid, object 错误内容对象(通常是消息串,无错误设null));

    当验证发生错误时会发生(不会触发任何异常): 
    1. 相应的单元周围出现红色框; 
    2. 单元上的关联属性Validation.HasErrorProperty变为True; 
    3. 单元上的关联属性Validation.ErrorsProperty中添加相应的ValidationError对象; 
    4. 如果相应Binding.NotifyOnValidationError设为True,则接力事件Validation.ErrorEvent被触发; 
    5. 相应的数据源不会更新到错误值。

    通过添加ExceptionValidationRule到ValidationRules中,可以使Binding中的任何异常都转变为上报验证错误。

    处理验证错误: 
    Validation.ErrorEvent的事件参数是ValidationErrorEventArgs,包含两个属性: 
    Action: 触发后首先是ValidationErrorEventAction.Added,当再次验证的时会首先清除前次的错误,再次触发事件,并使Action参数为ValidationErrorEventAction.Removed; 
    Error: 包含以下信息: 
    - object ErrorContent:  ValidationRule对象返回ValidationResult中设置的对象 
    - Exception Exception: 导致验证错误的异常(使用上述ExceptionValidationRule) 
    - BindingExpression BindingInError: 获得导致验证错误的Binding对应的BindingExpression,通过BindingExpression.ParentBinding可以得到Binding。 
    - RuleInError:获得对应的验证规则。

    15. 数据变更通知(Data Change Notification)

    自定义的数据源的数据更新往往通过: 
    1. 单独的数据对象,实现INotifyPropertyChanged接口实现, 
    在参数设置set过程中,调用PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("被改变的属性名"); 
    2. 集合数据对象,继承ObservableCollection,可直接依赖其内建的变更通知体系,则列表内容增删变更都会通知。一般形式: 
    class MyItems : System.Collections.ObjectModel.ObservableCollection<MyItem> { … } 
    集合元素的对象必须实现INotifyPropertyChanged以完成自身的变更通知。

    当显式设置Binding.NotifyOnSourceUpdated=”True”时,数据变更会触发接力事件Binding.SourceUpdatedEvent。

  • 相关阅读:
    Spring 中出现Element : property Bean definitions can have zero or more properties. Property elements correspond to JavaBean setter methods exposed by the bean classes. Spring supports primitives, refer
    java定时器schedule和scheduleAtFixedRate区别
    hql语句中的select字句和from 字句
    使用maven搭建hibernate的pom文件配置
    Failure to transfer org.apache.maven:maven-archiver:pom:2.5 from http://repo.maven.apache.org/ maven2 was cached in the local repository, resolution will not be reattempted until the update interv
    对于文件File类型中的目录分隔符
    hibernate的事务管理和session对象的详解
    解决mac 中的myeclipse控制台中文乱码问题
    ibatis selectKey用法问题
    Java中getResourceAsStream的用法
  • 原文地址:https://www.cnblogs.com/sjqq/p/6626362.html
Copyright © 2011-2022 走看看