zoukankan      html  css  js  c++  java
  • WPF学习(4) – WPF中的数据绑定

    1. 绑定对象

    数据绑定是通过System.Windows.Data.Binding对象来实现,它能够将2个属性绑定在一起,在接下来的应用程序生命周期中让绑定来负责所有的同步工作。

    1.1 在代码中实现

    绑定代码

    Binding binding = new Binding();

    //设置源对象

    binding.Source = treeview;

    //设置源属性

    binding.Path = new PropertyPath("SelectedItem.Header");

    //添加到目标属性

    currentFolder.SetBinding(TextBlock.TextProperty, binding);

    解除绑定代码

    BindingOperation.ClearBinding(currentFolder, TextBlock.TextProperty); //清除currentFolder的TextBlock

    BindingOperation.ClearAllBindings(currentFolder)  //清除所有和currentFolder有关的绑定

    1.2 在XAML中使用绑定

    <TextBlock x:Name="currentFolder" DockPanle.Dock="Top" Text="{Binding SelectedItem.Header, ElementName=treeview}"/>

    1.3 与普通的.NET属性绑定

    可以绑定.NET的对象的普通属性,如:

    <Label x:Name="numItemsLabel" Content="{Binding Source={StaticResource photoes}, Path=Count}" DockPanel.Dock="Bottom"/>

    虽然可以用,但是有弊端。因为普通的.NET对象属性和WPF中的依赖属性相比, 没有自动的变更机制支持。

    为了让目标和源属性保持同步,源对象必须实现以下技术中的一种:

    • 实现System.ComponentModel.INotifyPropertyChanged接口,该接口有一个PropertyChanged事件。
    • 实现XXXChanged事件,其中XXX是值发生改变的属性的名称。

    常用的是第一种,WPF对其进行了优化。

    1.4 绑定到整个对象

    绑定中的Path是可选的,你可以绑定整个对象。

    这种绑定方式对于那些能够充分利用对象的元素,比如ListBox, 是非常有用的。

    1.5 绑定到集合

    浅数据绑定

    例如,绑定一个对象到ListBox, 但是不能绑定到Items属性, 因为Items不是依赖属性。

    所以我们使用ListBox.ItemSource属性

    改进显示方式

    默认绑定集合的显示方式,用ToString呈现,并不能让人接受。可以使用DisplayMemberPath属性和ItemSource配合。

    <ListBox x:Name="pictureBox" DisplayMemberPath="Name" ItemSoruce="{Binding Source={StaticResource photos}}"

    </ListBox>

    管理选中项

    <ListBox IsSynchronizedWithCurrentItem="True" DisplayMemeberPath="Name" ItemSource="{Binding Source={StaticResource photos}}"></ListBox>

    <ListBox IsSynchronizedWithCurrentItem="True" DisplayMemeberPath="DateTime" ItemSource="{Binding Source={StaticResource photos}}"></ListBox>

    <ListBox IsSynchronizedWithCurrentItem="True" DisplayMemeberPath="Size" ItemSource="{Binding Source={StaticResource photos}}"></ListBox>

    因为设置了IsSynchronizedWithCurrentItem为True, 所有指向同一个源的的控件,改变任何一个控件的选中项都会同时改变其他两个控件。

    1.6 使用DataContext共享数据源

    使用DataContext指定共享数据源,下面的数据绑定,就可以简化。

    <StackPanel x:Name="parent" DataContext="{StaticResource photos}">

    <ListBox IsSynchronizedWithCurrentItem="True" DisplayMemeberPath="Name" ItemSource="{Binding}"></ListBox>

    <ListBox IsSynchronizedWithCurrentItem="True" DisplayMemeberPath="DateTime" ItemSource="{Binding}"></ListBox>

    <ListBox IsSynchronizedWithCurrentItem="True" DisplayMemeberPath="Size" ItemSource="{Binding}"></ListBox>

    </StackPanel>

    2. 控制呈现

    WPF中使用数据模板和值转换器来控制控件的呈现

    2.1 使用数据模板

    很多控件都提供一些属性可以用来添加数据模板。例如ContentControl的ContentTemplate属性, ItemControl的ItemTemplate属性,HeaderedContentControl的HeaderTemplate属性。

    <ListBox x:Name="pictureBox" ItemSource="{Binding Source={StaticResource photos}}">

    <ListBox.ItemTemplate>

         <DataTemplate>

               <Image Source="{Binding Path=FullPath}" Height="35"/>

         <DataTemplate>

    </ListBox.ItemTemplate>

    </ListBox>

    2.2 使用值转换器

    对不兼容的数据类型做桥接

    在数据绑定的时候,我们常常不能够直接使用,而需要转换。

    比如实现一个bug记录软件,当bug数目超过600的时候,显示bug的数字背景要用红色。颜色的属性如何和bug数目绑定呢?

    可以用值转换器来实现

    <Label Background=“Binding Path=Count,Converter={StaticResource myConverter}, Source={StaticResource photos}”/>

    实现的值转换器必须实现IValueConverter接口。IValueConverter接口有两个简单的方法——Convert和ConvertBack.

    自定义数据显示

    有时候虽然不存在数据类型不兼容的情况,但是我们可以使用值转换器来达到让结果更加易读的目的。

    3. 定制一个集合的视图

    事实上,无论何时绑定到一个集合(任何实现了IEnumerable的类), 都会有一个默认的视图隐式地被插入到源对象和目标对象之间。

    该视图(它是一个实现了ICollectionView接口的对象)存储着当前项的信息,但是它也支持排序、分组、过滤和项导航。

    3.1 排序

    ICollectionView有一个SortDescriptions属性提供了一种方式来控制视图项如何进行排序。

    //获取默认视图

    ICollectionView view = CollectionViewSource.GetDefaultView(this.FindResource("photos"));

    //清空以后的排序

    view.SortDescriptions.Clear();

    //添加排序

    view.SortDescriptions.Add(new SortDescription('Name', ListSortDirection.Ascending));

    3.2 分组

    ICollectionView有一个GroupDescription属性,用它可以把源集合的项放入组和子组中。

    3.3 过滤

    属性Filter是一个委托,返回bool类型。

    3.4 导航

    view支持导航数据的能力,提供了如下这些方法和属性

    IsCurrentBeforeFirst, IsCurrentAfterLast

    MoveCurrentToPrevious(), MoveCurrentToLast() 等

    3.5 使用其他视图

    可以显式手动创建视图,而不是使用默认的视图。 下面是用CollectionViewSource创建的一个复杂的视图。

    <Window.Resources>

        <local:Photos x:Key="photos"/>

        <CollectionViewSource x:Key="ViewSource" Source="{StaticResource photos}" Filter="viewSource_Filter" Source="{StaticResource photos}">

        <CollectionViewSource.SortDescriptions>

                <componentModel:SortDescription PropertyName="DateTime" Direction="Descending"/>

        </CollectionViewSource.SortDescriptions>

        <CollectionViewSource.GroupDescriptions>

                <PoropertyGroupDescription PropertyName="DateTime"/>

        </CollectionViewSource.GroupDescriptions>

    </WIndow.Resources>

    4. 数据提供程序

    源对象可以是任意的.NET对象,所以你有足够的代码来执行任何数据绑定。

    所以我们只要实现一个合适的.NET对象,可以提供正确的属性集合和通知机制,就可以更加方便的构造自己的数据源。

    为了方便,WPF提供了2个类XamlDataProvider和ObjectDataProvider

    4.1 XMLDataProvider

    一个例子

    <Window.Resource>

         <XmlDataProvider x:Key="dataProvider" XPath="GameStats">

                <x:XData>

                 ...................

                </x:XData>

         </XmlDataProvider>

    </Window.Resource>

    <ListBox ItemsSource="{Binding Source={StaticResource dataProvider}, XPath=GameStat/HighScore}"

    这里dataProvider是一个Windows Resource的key, 这个资源是一段xml文本, XPath指出了数据绑定的节点路径。

    4.2 ObjectDataProvider

    我们已经实现了使用.NET对象作为绑定的数据源了,那么使用ObjectDataProvider的意义在哪里呢?

    它可以实现:

    • 声明式地使用带参数的构造函数实现实例化源对象。
    • 绑定到源对象的一种方法。
    • 有更多的选项来做异步数据绑定。

    在XAML中使用带参数的构造函数

    <ObjectDataProvider x:Key="dataProvider" ObjectType="{x:Type local:Photos}">

    <ObjectDataProvider.ConstructorParameters>

         <sys:Int32>23</sys:Int32>

    </ObjectDataProvider.ConstructorParameters>

    </OjbectDataProvider>

    ObjectProvider可以是一个方法

    <ObjectDataProvider x:Key="dataProvider" OjbectType=“{x:Type local:Photos}" MethodName="GetFolderName"/>

    5. 高级主题

    5.1 自定义Binding的数据流

    可以通过设置Binding的Mode属性来改变绑定的数据流。

    Mode可以是BindingMode枚举值:

    • OneWay, 当源改变时,目标会被更新。
    • TwoWay, 源或目标改变,都会导致另一方一起被更新。
    • OneWayToSoruce, 和OneWay相反,当目标改变时,源都会被更新。
    • OneTime, 和OneWay一样工作,但源的改变不会被反映到目标上。目标会保留Binding初始化时源的一个快照。

    TwoWay绑定适合于数据绑定表单, 因为在表单中你可能会有一些运行用户修改数据的TextBox, 且这些TextBox已经被填入了数据。

    事实上,虽然大多数依赖属性默认都是OneWay绑定,但像TextBox.Text这样的依赖属性是TwoWay绑定的。

    5.2 向绑定添加验证规则

    我们可以在绑定的时候,添加验证规则。

    验证规则类需要继承ValidationRule, 重写方法ValidationResult

    <TextBox>

         <TextBox.Text>

               <Binding ...>

                    <Binding.ValidationRules>

                           <local:JpgValicationRule/>

                    </Binding.ValidationRules>

               </Binding>

         </TextBox.Text>

    </TextBox>

  • 相关阅读:
    将网站从WSS2.0升级到WSS3.0的心得
    Teched 2008课程:ADO.NET Data Service & UC开发概览
    我的基于Silverlight2的相册,也刚刚升级到了RTW了。
    ubuntu16.04设置python3为默认及一些库的安装
    CDMA手机的MEID
    CDMA Subscription 模式设置
    Android架构纵横谈之——软件自愈能力(转载)
    CDMA系统中的用户识别卡(UIM)和空中激活技术(OTA)
    手机信号强度全解析
    GSMPhone与CDMAPhone切换过程
  • 原文地址:https://www.cnblogs.com/JustRun1983/p/2647249.html
Copyright © 2011-2022 走看看