数据绑定细节
要使用 WPF 数据绑定功能,您必须始终要有目标和源。绑定的目标可以是从 DependencyProperty 派生而来的任何可访问属性或元素,例如 TextBox 控件的 Text 属性。绑定的源可以是任何公共属性,包括其他控件、公共语言运行库 (CLR) 对象、XAML 元素、ADO.NET Dataset、XML 片段等的属性。为了帮助您正确实现绑定,WPF 包含了两个特殊的提供程序:XmlDataProvider 和 ObjectDataProvider。
现在让我们看一下 WPF 数据绑定技术的工作原理,我将列举一些实用的示例来说明它们的用法。
创建简单的绑定
首先,我们来看一个简单的示例,该示例说明了如何将 TextBlock 的 Text 属性绑定到 ListBox 的选定项。图 1 中的代码显示的是声明了六个 ListBoxItem 的 ListBox。该代码示例中的第二个 TextBlock 具有名为 Text(使用 XML 子元素 <TextBlock.Text> 在 XAML 属性元素语法中指定)的属性,它将包含 TextBlock 的文本。Text 属性声明了通过 <Binding> 标记与 ListBox 选定项的绑定。Binding 标记的 ElementName 属性指示 TextBlock 的 Text 属性要与其绑定的控件的名称。Path 属性指示我们将绑定到的元素(在本例中是 ListBox)的属性。此代码产生的结果是,如果从 ListBox 选择了一种颜色,该颜色的名称则会在 TextBlock 中显示。
Figure 1 基本但详细的控件绑定
<StackPanel><TextBlock Width="248" Height="24" Text="Colors:" TextWrapping="Wrap"/><ListBox x:Name="lbColor" Width="248" Height="56"><ListBoxItem Content="Blue"/><ListBoxItem Content="Green"/><ListBoxItem Content="Yellow"/><ListBoxItem Content="Red"/><ListBoxItem Content="Purple"/><ListBoxItem Content="Orange"/></ListBox><TextBlock Width="248" Height="24" Text="You selected color:" /><TextBlock Width="248" Height="24"><TextBlock.Text><Binding ElementName="lbColor" Path="SelectedItem.Content"/></TextBlock.Text></TextBlock>
</StackPanel>

为了使用简单的语法来进行数据绑定,可以对图 1 中列出的代码稍加修改。例如,我们用下列代码段替代 TextBlock 的 <Binding> 标记:
<TextBlock Width="248" Height="24" Text="{Binding ElementName=lbColor, Path=SelectedItem.Content}" />

这种语法称为属性语法,它压缩了 TextBlock 的 Text 属性内部的数据绑定代码。基本上,Binding 标记会连同它的属性一起被归入大括号内。
绑定模式
我可以继续以上述示例为例,将 TextBlock 的背景色绑定到在 ListBox 中选择的颜色。以下代码可将 Background 属性添加到 TextBlock 中,并使用该属性的绑定语法将其绑定到 ListBox 中选定项的值:
<TextBlock Width="248" Height="24"
Text="{Binding ElementName=lbColor, Path=SelectedItem.Content, Mode=OneWay}"
x:Name="tbSelectedColor"
Background="{Binding ElementName=lbColor, Path=SelectedItem.Content, Mode=OneWay}"/>

如果用户在 ListBox 中选择了一种颜色,那么该颜色的名称就会出现在 TextBlock 中,并且 TextBlock 的背景色会变为选定的颜色(请参见图 2 )。

图 2 将一个源绑定到两个目标

请注意前一个示例中将 Mode 属性设为 OneWay 的语句。Mode 属性用于定义绑定模式,它将决定数据如何在源和目标之间流动。除 OneWay 之外,还有另外三种绑定模式:OneTime、OneWayToSource 和 TwoWay。
正如前面的代码段中所示,使用 OneWay 绑定时,每当源发生变化,数据就会从源流向目标。尽管我在示例中显式指定了此绑定模式,但其实 OneWay 绑定是 TextBlock 的 Text 属性的默认绑定模式,无需对其指定。和 OneWay 绑定一样,OneTime 绑定也会将数据从源发送到目标;但是,仅当启动了应用程序或 DataContext 发生更改时才会如此操作,因此,它不会侦听源中的更改通知。与 OneWay 和 OneTime 绑定不同,OneWayToSource 绑定会将数据从目标发送到源。最后,TwoWay 绑定会将源数据发送到目标,但如果目标属性的值发生变化,则会将它们发回给源。
在上述示例中,我使用了 OneWay 绑定,因为我希望只要 ListBox 选择发生变化,就将源(选定的 ListBoxItem)发送到 TextBlock。我不希望 TextBlock 的更改再回到 ListBox。当然,用户无法编辑 TextBlock。如果我想使用 TwoWay 绑定,可以将 TextBox 添加到此代码中,将其文本和背景色绑定到 ListBox,并将 Mode 属性设为 TwoWay。用户在 ListBox 中选择一种颜色后,该颜色就会显示在 TextBox 中,并且其背景色会相应变化。如果该用户在 TextBox 中键入了一种颜色(例如蓝绿色),ListBox 中的颜色名称就会更新(从目标到源),反过来,因为 ListBox 已经更新,所以此新值就会被发送到绑定到 ListBox 的 SelectedItem 属性的所有元素。这意味着 TextBlock 也会更新其颜色,并且将其文本值设置为该新的颜色(请参见图 3 )。

图 3 运行中的 TwoWay 绑定

下面是我刚才用来将 TextBlock (OneWay) 和 TextBox (TwoWay) 绑定到 ListBox 的代码:
<TextBlock Width="248" Height="24" Text="{Binding ElementName=lbColor, Path=SelectedItem.Content,Mode=OneWay}" x:Name="tbSelectedColor" Background="{Binding ElementName=lbColor, Path=SelectedItem.Content, Mode=OneWay}"/>

<TextBox Width="248" Height="24" Text="{Binding ElementName=lbColor, Path=SelectedItem.Content, Mode=TwoWay}" x:Name="txtSelectedColor" Background="{Binding ElementName=lbColor, Path=SelectedItem.Content, Mode=OneWay}"/>

如果我将 TwoWay 模式改回到 OneWay,用户则可以编辑 TextBox 中的颜色,且不会导致更改过的值被发回给 ListBox。
选择合适的绑定模式非常重要。当我想向用户显示只读数据时,我通常会采用 OneWay 模式。当我希望用户可以更改控件中的数据,并且让该变化能在数据源(DataSet、对象、XML 或其他绑定控件)中体现出来时,我会使用 TwoWay 绑定。如果想让用户在数据源不将其数据绑定到目标的情况下更改数据源,我发现 OneWayToSource 是个不错的选择。我曾经接到一个任务,要求在只读控件中显示与加载屏幕时一样的数据状态。在这个任务中,我使用了 OneTime 绑定。通过使用 OneTime 绑定,一系列只读控件均被绑定到了数据,并且当用户与表单交互且数据源的值发生更改时,绑定控件仍保持不变。这为用户提供了一种比较所发生更改的方法。此外,当源没有实现 INotifyPropertyChanged 时,OneTime 绑定也是一个不错的选择。
绑定的时间
在上述示例中,TextBox 允许 TwoWay 绑定到在 ListBox 中选定的 ListBoxItem。这会使数据在 TextBox 失去焦点时从 TextBox 流回 ListBox。为了改变导致将数据发送回源的这种情况,可以为 UpdateSourceTrigger 指定值,它是用于定义何时更新源的绑定属性。可以为 UpdateSourceTrigger 设置三个值:Explicit、LostFocus 和 PropertyChanged。
如果将 UpdateSourceTrigger 设置为 Explicit,则不会更新源,除非从代码调用 BindingExpression.UpdateSource 方法。LostFocus 设置(TextBox 控件的默认值)指示源在目标控件失去焦点时才会更新。PropertyChanged 值指示目标会在目标控件的绑定属性每次发生更改时更新源。如果您想指示绑定的时间,该设置非常有用。
绑定到 XML
绑定到数据源(例如 XML)和对象同样也非常方便。图 4 显示了 XmlDataProvider 的示例,其中包含将用作数据源的颜色的嵌入式列表。XmlDataProvider 可用来绑定到 XML 文档或片断,该文档或片段既可以嵌入在 XmlDataProvider 标记中,也可以位于外部位置引用的文件中。
Figure 4 XmlDataProvider
<StackPanel>
<StackPanel.Resources>
<XmlDataProvider x:Key="MoreColors" XPath="/colors"><x:XData><colors ><color name="pink"/><color name="white"/><color name="black"/><color name="cyan"/><color name="gray"/><color name="magenta"/></colors></x:XData>
</XmlDataProvider>

嵌入式 XML 内容必须置于 XmlDataProvider 内部的 <x:XData> 标记中,如图 4 所示。必须为 XmlDataProvider 提供 x:Key 值,以便数据绑定目标可对其进行引用。请注意,XPath 属性设置为“/colors”。此属性定义了将用作数据源的 XML 内容的级别。当绑定到可能包含在文件或数据库中的较大 XML 结构,且想要绑定的数据不是根元素时,这一属性会变得非常有用。
XmlDataProvider 是可放置到特定上下文资源内部的一种资源。如图 4 所示,已将 XmlDataProvider 定义为 StackPanel 上下文中的资源。这意味着 XmlDataProvider 将可用于该 StackPanel 内部的所有内容。设置资源的上下文有助于限制数据源向合适的区域公开。这使您可以在页面内分别为控件和支持资源创建定义明确的独立区域,从而提高可读性。
绑定到资源的语法与绑定到元素的语法略有不同。绑定到控件时,可以设置绑定的 ElementName 和 Path 属性。但是绑定到资源时,需要设置 Source 属性,由于我们是绑定到 XmlDataProvider,所以还要设置绑定的 XPath 属性。例如,下列代码可将 ListBox 的项绑定到 MoreColors 资源。将 Source 属性设置为资源,并将其指定为名为 MoreColors 的 StaticResource。XPath 属性指示项会绑定到 XML 数据源中 <color> 元素的名称属性:
<ListBox x:Name="lbColor" Width="248" Height="56" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource MoreColors}, XPath=color/@name}">
</ListBox>

我在本例中指定了 StaticResource,因为 XML 不会发生更改。如果数据源发生了更改,则不会将这些更改发送到目标。DynamicResource 设置则表示相反的情况,即会将数据源的更改发送到目标。当引用系统主题、全球化语言或字体时,该设置非常有用。DynamicResource 将允许这些类型的设置被传送到与其动态绑定的所有 UI 元素中。
XmlDataProvider 也可以指向 XML 内容的外部源。例如,我有一个名为 colors.xml 的文件,其中包含我希望 ListBox 绑定到的颜色列表。我只需要将第二个 XmlDataProvider 资源添加到 StackPanel,并将其引向 XML 文件即可。请注意,我将 Source 属性设置为了 XML 文件的名称,并将 x:Key 设置为 Colors:
<XmlDataProvider x:Key="Colors" Source="Colors.xml" XPath="/colors"/> 

两个 XmlDataProvider 在同一个 StackPanel 中都作为资源而存在。我可以使 ListBox 将其本身绑定到这个新的资源,方法是更改 StaticResource 设置的名称:
<ListBox x:Name="lbColor" Width="248" Height="56" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource Colors}, XPath=color/@name}">
</ListBox>

对象绑定和 DataTemplates
虽然 XmlDataProvider 对 XML 非常有用,但是当您想绑定到对象或对象列表时,可以创建 ObjectDataProvider 作为资源。ObjectDataProvider 的 ObjectType 指定将提供数据绑定源的对象,而 MethodName 则指示为获得数据而需调用的方法。例如,假设我有一个名为 PersonService 的类,该类使用一种名为 GetPersonList 的方法来返回列表 <Person>,那么 ObjectDataProvider 可能会如下所示:
<StackPanel.Resources>
<ObjectDataProvider x:Key="persons"
ObjectType="{x:Type svc:PersonService}"
MethodName="GetPersonList"></ObjectDataProvider>
</StackPanel.Resources>

如果您想进行更全面的了解,本栏随附的代码中还包含了 PersonService 和 Person 类以及其他示例代码。
ObjectDataProvider 还可以使用许多其他属性。ConstructionParameters 属性允许您将参数传递给要调用的类的构造函数。此外,可以使用 MethodParameters 属性来指定参数,同时还可以使用 ObjectInstance 属性来指定现有的对象实例作为源。
如果希望异步检索数据,可以将 ObjectDataProvider 的 IsAsynchronous 属性设为 true。这样,用户将可以在等待数据填充绑定到 ObjectDataProvider 的源的目标控件时与屏幕进行交互。
在添加 ObjectDataProvider 时,必须限定数据源类的命名空间。在本例中,我必须将 xmlns 属性添加到 <Window> 标记中,以便 svc 快捷方式符合要求,并指示正确的命名空间:
xmlns:svc="clr-namespace:DataBindingWPF"

既然数据源已通过 ObjectDataProvider 定义,接着我想将 ListBox 控件中的项绑定到此数据。我想在每个 ListBoxItem 中显示两行文本。第一行将以粗体显示 Person 实例的 FullName 属性,第二行将显示该实例的 Title 和 City。在 XAML 中,通过使用 DataTemplate,这是很容易实现的,DataTemplate 允许您定义可重用的数据可视化策略。
图 5 显示了完整的 XAML,其中将 DataTemplate 定义为在我指定的布局中显示 Person 信息。我设置了 DataTemplate 的 DataType 属性,以指示 DataTemplate 将会引用 Person 类类型。我没有在 DataTemplate 中指定真正的绑定,因为我会在 ListBox 控件中指定。通过省略绑定源,可对作用域内的当前 DataContext 执行绑定。
图 5 中,我将 ListBox 的 ItemsSource 属性设置为绑定到人员资源,以便我可以将数据绑定到 ListBox,而不用对它进行格式化。通过将 ItemTemplate 属性设置为 PersonLayout 资源(即 DataTemplate 的键名),可以正确显示数据。最终结果的屏幕如图 6 所示。
Figure 5 对象绑定
<Window x:Class="DataBindingWPF.ObjectBinding"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:svc="clr-namespace:DataBindingWPF"
Title="DataBindingWPF" Height="300" Width="300">
<StackPanel><StackPanel.Resources><ObjectDataProvider x:Key="persons" ObjectType="{x:Type svc:PersonService}" MethodName="GetPersonList" ></ObjectDataProvider><DataTemplate x:Key="personLayout" DataType="Person"><StackPanel Orientation="Vertical"><TextBlock Text="{Binding Path=FullName}" FontWeight="Bold" Foreground="Blue"></TextBlock><StackPanel Orientation="Horizontal"><TextBlock Text="{Binding Path=Title}"></TextBlock><TextBlock Text=", "></TextBlock><TextBlock Text="{Binding Path=City}"></TextBlock></StackPanel></StackPanel></DataTemplate></StackPanel.Resources><TextBlock></TextBlock><ListBox x:Name="lbPersons" ItemsSource="{Binding Source={StaticResource persons}}" ItemTemplate="{DynamicResource personLayout}" IsSynchronizedWithCurrentItem="True"/>
</StackPanel>
</Window>

图 6 使用 DataTemplate

对数据进行排序
如果想以特定的方式对数据进行排序,可以绑定到 CollectionViewSource,而不是直接绑定到 ObjectDataProvider。CollectionViewSource 则会成为数据源,并充当截取 ObjectDataProvider 中的数据的媒介,并提供排序、分组和筛选功能,然后将它传送到目标。
接着显示的 CollectionViewSource 将其 Source 属性设置为 ObjectDataProvider(人员)的资源名称。然后我通过指示排序依据的属性及其方向定义了数据的排序顺序:
<CollectionViewSource x:Key="personView" Source="{Binding Source={StaticResource persons}}"><CollectionViewSource.SortDescriptions><ComponentModel:SortDescription 

PropertyName="City" Direction="Ascending" />    <ComponentModel:SortDescription PropertyName="FullName" Direction="Descending" /></CollectionViewSource.SortDescriptions>
</CollectionViewSource>

DataContext 可用来将容器控件内部的所有控件都绑定到数据源中。当您拥有多个控件,而且这些控件全部使用同一个绑定源时,这非常有用。如果为每个控件都指定了绑定源,那么代码可能会重复。相反,可以将容器控件的 DataContext 设置为绑定源,然后只需从所包含的控件中省略 Source 属性即可。例如,下面是一系列显式绑定到同一个绑定源的 TextBlock:
<StackPanel>
<TextBlock Text="{Binding Source={StaticResource personView}, Path=FullName}"></TextBlock>
<TextBlock Text="{Binding Source={StaticResource personView}, Path=Title}"></TextBlock>
<TextBlock Text="{Binding Source={StaticResource personView}, Path=City}"></TextBlock>
</StackPanel>

以下是绑定到 DataContext 的三个相同的 TextBox,在此处,DataContext 反过来引用了该控件的 StackPanel 容器:
<StackPanel DataContext="{Binding Source={StaticResource personView}}" >
<TextBlock Text="{Binding Path=FullName}"></TextBlock>
<TextBlock Text="{Binding Path=Title}"></TextBlock>
<TextBlock Text="{Binding Path=City}"></TextBlock>
</StackPanel>

如果该容器没有定义 DataContext,那么它会继续查找下一个外部嵌套容器,直到它找到当前的 DataContext 为止。

转载于:https://www.cnblogs.com/fanguizhang/archive/2012/08/16/Binding.html

转载:WPF binding相关推荐

  1. WPF入门教程系列(二) 深入剖析WPF Binding的使用方法

    同一个对象(特指System.Windows.DependencyObject的子类)的同一种属性(特指DependencyProperty)只能拥有一个binding. 这一点可以通过设置bindi ...

  2. WPF Binding(四种模式)

    WPF Binding(四种模式) 在使用Binding类的时候有4中绑定模式可以选择 BindingMode TwoWay 导致对源属性或目标属性的更改可自动更新对方.此绑定类型适用于可编辑窗体或其 ...

  3. WPF Binding(绑定)详解

    Binding概念理解: WPF为了实现了UI与数据逻辑的解耦,将UI从数据逻辑中分离出来形成Xaml文件,而UI与数据逻辑之间的联系则通过Bingding来实现.Bingding就像UI与数据逻辑之 ...

  4. 为什么这儿TemplateBinding不起作用了—研究WPF Binding(一)

    工作中,写自定义控件,遇到一个奇怪的问题.场景是这样的:一个ListBox或其他ItemsControl显示数据列表,下方一个TextBlock显示列表中选定的值,代码大概是这样的(做了简化): &l ...

  5. [转载]WPF – 使用触发器

    WPF提供了很重要的一个东西就是绑定Binding, 它帮助我们做了很多事情,这个我们在WPF学习之绑定这篇里边有讲过.对于Binding我们可以设置其绑定对象,关系,并通过某种规则去验证输入,或者转 ...

  6. WPF Binding

    Binding的亮点 在WPF中,Binding无处不在,关于Binding的漂亮用法有很多,其主要的设计亮点有二: Weak Event模式 Converter 监听B的属性变化,A需要注册B的Pr ...

  7. Wpf Binding.Path设置

    Binding.Path 获取或设置绑定源属性的路径. 每个绑定通常都具有四个组件:绑定目标对象.目标属性.绑定源,以及要使用的绑定源值的路径.有关这些数据绑定概念的更多信息,请参见数据绑定概述. 使 ...

  8. 转载 WPF 控件模板 数据模板 面板模板

    转载自:https://blog.csdn.net/ceasadan/article/details/61414879 模板使用方式:首先定义模板,然后在把对应的key应用到控件对应的属性中: 属性对 ...

  9. [转载]WPF控件拖动

    这篇博文总结下WPF中的拖动,文章内容主要包括: 1.拖动窗口 2.拖动控件 Using Visual Studio 2.1thumb控件 2.2Drag.Drop(不连续,没有中间动画) 2.3拖动 ...

最新文章

  1. 在yii2中,让你action参数支持POST数据的小方法
  2. 使用c语言读写netcdf文件,[原][c][netcdf]读取函数
  3. UVA 141 The Spot Game
  4. Netflix在安卓移动启用AV1格式 较VP9编码效率提升20%
  5. c#语言中读取txt文件,简单的c#文本文件读写-.NET教程,C#语言
  6. XXX集团财务决策支持系统——财务分析指标(系列五)
  7. 批量修改数据_#泰Q头条#065期 四步搞定Excel表中的批量数据修改
  8. Linux下dd查看磁盘的读写性能
  9. iPhone 12再陷“信号门”:用户称每天需多次重启恢复;蚂蚁集团打新资金退款如期到账;Mutt 2.0 发布|极客头条
  10. linux中用shell获取时间,日期
  11. java常见面试题:Java程序员面试题(五)
  12. 测试时的一些技巧及面试官的一些期望回答
  13. matlab textscan溢出,matlab - Textscan存档有大量的行 - 堆栈内存溢出
  14. dell电脑装双系统linux,戴尔电脑怎么装双系统?戴尔装win7+win10双系统详细教程
  15. 从头到尾彻底解析Hash 表算法
  16. 【超快捷】Windows系统自带的快捷键合集
  17. wpf 打开输入法、禁用输入法
  18. chfs http 文件共享服务
  19. ForestBlog博客源码学习笔记
  20. 写给还在迷茫中的朋友,一名6年程序员的工作感悟!!!

热门文章

  1. Twemproxy测试Redis分片主从架构
  2. “是男人就下100层”
  3. 第十二天--Property List和NSUserDefaults
  4. SQL Server 自动更新统计信息的基本算法
  5. 给超链接A添加按钮样式
  6. redis aof持久化
  7. RabbbitMq 消费端自定义监听
  8. 3 RabbitMQ高级特性 3
  9. golang 筆記:make 與 new 的差別
  10. laravel 安装后500错误