到目前为止都在讨论如何链接两个元素的绑定。但在数据驱动的应用程序中,更常见的情况是创建从不可见的对象中提取数据绑定表达式。唯一的要求是希望显示的信息必须存储在公有的属性中。WPF数据绑定基础结构不能获取私有信息或共有字段。

当绑定到非元素对象时,需要放弃Binding.ElementName属性,并使用一下属性中的一个:

Source:该属性是指向源对象的引用---换句话说,是提供数据的对象。

RelativeSource:这是引用,使用RelativeSource对象指向源对象。有了这个附加层,可以在当前元素(包含绑定表达式的元素)的基础之上构建引用。这个似乎无所谓地增加了复杂程度,但实际上,ReltiveSource属性是一种特殊工具,当编写控件模板以及数据模版时是很方便的。

DataContext:如果没有使用ReltiveSource和Source属性指定源,WPF就从当前元素开始在元素树上向上查找。检查每个元素的DataContext属性,并使用第一个非空的DataContect属性。当我要将同一个对象的多个属性绑定到不同元素的时候,DataContext属性是非常有用的,因为可以在更高层次的容器对象上(而不是直接在目标元素上)设置DataContext属性。

接下来详细介绍这三个属性的更多细节。

Source属性:

Source属性非常简单。唯一的问题是为了进行绑定,需要具有数据对象。在稍后将会看到,可以用几种方法获取对象。可从资源中提取数据对象,可以通过编写代码生成数据对象,也可以在数据提供程序的帮助下获取数据对象。

最简单的选择是将Source属性指向一些已经准备好了静态对象。例如:可以在代码中创建一个静态对象并使用该对象。或者,可以使用来自.NET类库的组件,如下所示:

<Window x:Class="Test1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="" Width="">
<Grid>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}"></TextBlock>
</Grid>
</Window>

这个绑定表达式获取由静态属性SystemFonts.IconFamily提供的FontFamily对象(注意,为了设置Binding.Source属性,需要借助静态标记扩展)。然后将Binding,Path属性设置为FontFamily.Source属性,该属性给出了字体家族的名称。结果是一行文本。

另一种选择是绑定到先前作为资源创建的对象。例如,下面的标记创建的指向Calibri字体的FontFamily对象:

<Window x:Class="Test1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="" Width="">
<Window.Resources>
<FontFamily x:Key="CustomFont">Calibri</FontFamily>
</Window.Resources>
<Grid>
<TextBlock Text="{Binding Source={StaticResource CustomFont},Path=Source}"></TextBlock>
</Grid>
</Window>

RelativeSource属性:

通过RelativeSource属性可以根据相对目标对象的关系指向源对象。例如:可以使用RelativeSource属性将元素绑定到自身或其父元素(不知道在元素树中从当前元素到绑定的父元素之间有多少代)。

为设置Binding.RelativeSource属性,需要使用RelativeSource对象。这会使得语法变得更加复杂,因为除了需要创建Binding对象外,还需要在其中创建嵌套的RelativeSource对象。一种选择是使用属性设置语法而不是Binding标记扩展。例如,下面的代码为TextBlock.Text属性创建了一个Binding对象,这个Binding对象使用查找父窗口并显示窗口标题的RelativeSource对象:

<Window x:Class="Test1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="" Width="">
<Window.Resources>
<FontFamily x:Key="CustomFont">Calibri</FontFamily>
</Window.Resources>
<Grid>
<TextBlock>
<TextBlock.Text>
<Binding Path="Title">
<Binding.RelativeSource>
<RelativeSource Mode="FindAncestor" AncestorType="{x:Type Window}"/>
</Binding.RelativeSource>
</Binding>
</TextBlock.Text>
</TextBlock>
</Grid>
</Window>

RelativeSource对象使用FindAncestor模式,该模式告知查找元素树知道发现AncestorType属性定义的元素类型。

编写绑定更常用的方法是使用Binding和RelativeSource标记扩展,将其合并到一个字符串中,如下所示:

<Window x:Class="Test1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="" Width="">
<Window.Resources>
<FontFamily x:Key="CustomFont">Calibri</FontFamily>
</Window.Resources>
<Grid>
<TextBlock Text="{Binding Path=Title,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}">
</TextBlock>
</Grid>
</Window>

当创建RelativeSource对象时,FindAncestor模式有4种,表8-3列出了所有4种模式
表8-3 RelativeSourceMode枚举值

self:表达式绑定到同一元素的另一个元素属性上;

FindAncestor:表达式绑定到父级元素。WPF将查找元素树直至发现期望的父元素。为了指定父元素,还必须设置AncestorType属性以指示希望查找的父元素的类型。此外,还可以用AncestorLevel属性略过发现的一定数量的特定元素;

PreviousData:表达式绑定到数据绑定列表中的前一个数据项。在列表项中会使用这种模式

TemplateParent:表达式绑定到应用模板的元素。只有当绑定位于控件模板或数据模板内容时,这种模式才能工作

RelativeSource属性看似多余,并且会使标记变得复杂。毕竟,为什么不使用Source或者ElementName属性直接绑定到希望绑定的源呢?然而,并不总可以使用Source或ElementName属性,这通常是因为源对象和目标对象在不同的标记块中。当创建控件模板和数据模板时会出现这种情况。例如,如果正在构建改变列表项显示方式的数据模板,可能需要访问顶级的ListBox对象以读取属性。

DataContext属性

在某些情况下,会将大量元素绑定到同一个对象。例如,分析下面的一组TextBlock元素,每个TextBlock元素都使用类似的绑定表达式提取与默认图标相关图标字体相关的不同细节,包括行间距,以及第一个字体的样式和粗细(这两个都是简单的正则表达式)。可以为每个TextBlock元素使用Source属性,但这会使标记变得非常长:

<Window x:Class="Test1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="" Width=""> <StackPanel>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}">
</TextBlock>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=LineSpacing}"></TextBlock>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=FamilyTypefaces[0].Style}"></TextBlock>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=FamilyTypefaces[0].Weight}"></TextBlock>
</StackPanel>
</Window>

对于这种情况,使用FrameworkElement.DataContext属性一次性定义绑定源会更清晰,也更灵活。在这个示例中,为包含所有TextBlock元素的StackPanel面板设置DataContext属性是合理的(甚至还可以在更高层次上设置DataContext属性-例如整个窗口-但是为了使意图更清晰,在尽可能小的范围内进行定义效果更好)。

可以使用和是设置Binding.Source属性相同的方法设置元素的DataContext属性。换句话说,可以提供内联对象,从静态属性中提取,或从资源中提取。

当绑定表达式中省略源信息时,WPF会检查元素的DataContext属性。如果属性值为NULL,WPF会继续向上在元素树种查找第一个不为NULL的数据上下文(最初,所有元素的DataContext属性都是NULL)。如果找到了一个数据上下文,就为绑定使用找到的数据上下文。如果没有找到,绑定表达式不会为目标属性应用任何值。
————————————————
版权声明:本文为CSDN博主「大约In冬季」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wudong121/article/details/52073309

WPF:元素绑定的更多相关文章

  1. WPF元素绑定

    原文:WPF元素绑定 数据绑定简介:数据绑定是一种关系,该关系告诉WPF从源对象提取一些信息,并用这些信息设置目标对象的属性.目标属性是依赖项属性.源对象可以是任何内容,从另一个WPF元素乃至ADO. ...

  2. WPF 元素绑定

    1.什么是数据绑定数据绑定是一种关系,WPF程序从源对象中提取一些信息,并根据这些信息设置目标对象的属性,目标属性作为依赖项属性.源对象可以是任何内容,可以是另一个wpf内容,甚至是自行创建的纯数据对 ...

  3. 学习WPF——元素绑定

    概念 从源对象提取一些信息,并用这些信息设置目标对象的属性 示例 在给TextBlock控件的FontSize属性赋值时,我们使用了绑定表达式 数据绑定表达式使用XAML的标记扩展(因此具有花括号)( ...

  4. WPF学习笔记(一):数据绑定之元素到元素绑定

    前言 作为一只菜鸟,之前学了一段时间的WPF,但是没有总结,过了一学期发现好多东西都忘记了,很多东西还是需要记下来,以备后续复习. 数据绑定在事件中应用非常广泛,可以有效地减少代码量,那么什么是数据绑 ...

  5. WPF学习系列之六 (元素绑定)

    元素绑定 简单地说,数据绑定是一种关系,该关系告诉WPF从一个源对象提取一些信息,并使用这些信息设置目标对象的属性.目标属性总是依赖属性,并且通常位于WPF元素中. 一.将元素绑定到一起 <Wi ...

  6. 七,WPF的元素绑定

    数据绑定是一种关系,该关系告诉WPF从一个源对象提取一些信息,并使用这些信息设置目标对象的属性,目标属性总是依赖项属性,然而,源对象可以是任何内容. 源对象是WPF元素并且源属性是依赖项属性的数据绑定 ...

  7. 【WPF学习】第二十九章 元素绑定——将元素绑定到一起

    数据banding的最简单情形是,源对象时WPF元素而且源属性是依赖性属性.前面章节解释过,依赖项属性具有内置的更改通知支持.因此,当在源对象中改变依赖项属性的值时,会立即更新目标对象中的绑定属性.这 ...

  8. 【WPF学习】第三十章 元素绑定——绑定到非元素对象

    前面章节一直都在讨论如何添加链接两个各元素的绑定.但在数据驱动的应用程序中,更常见的情况是创建从不可见对象中提取数据的绑定表达式.唯一的要求是希望显示的信息必须存储在公有属性中.WPF数据绑定数据结构 ...

  9. wpf,visibility属性的多元素绑定及值转换

    visibility实现多元素绑定. 实现多绑定转换 public class VisibilityConverter : IMultiValueConverter { public object C ...

随机推荐

  1. String,int,Integer之间的转换

    public class Test{ public static void main(String[] args) { //int转换成Integer Integer in = new Integer ...

  2. Java-内存模型(JSR-133)

    Java 内存模型(Java Memory Model,JMM)看上去和 Java 内存结构(JVM 运行时内存结构)差不多,但这两者并不是一回事.JMM 并不像 JVM 内存结构一样是真实存在的,它 ...

  3. 5.Hiveguigun滚(ノ`Д)ノ竟然竞争谨慎谨慎谨慎哈喇子罢工八公

    1.Hive简介 2.Hive部署与安装 3.Hive的使用 4.Hive JDBC编程

  4. ElementTree 无法处理中文

    ElementTree.fromstring()  导入xml格式时,是可以选择解析parser的编码的,并且 它解析出来的node类型是 严谨且严格的,不会 自己内部全部转换成str,比如 9.87 ...

  5. OpenStack Blazar 架构解析与功能实践

    目录 文章目录 目录 Blazar Blazar 的安装部署 Blazar 的软件架构 Blazar 的资源模型与状态机 Blazar 的主机资源预留功能(Host Reservation) 代码实现 ...

  6. Pyqt5-QtWidget的使用

    QTableWidget是QTableViewer的子类 ,其中QTableViewer可以使用自定义的数据模型来显示内容(通过setModel ()来绑定数据源),而QTableWidget提供了一 ...

  7. Python:Base4(map,reduce,filter,自定义排序函数(sorted),返回函数,闭包,匿名函数(lambda) )

    1.python把函数作为参数: 在2.1小节中,我们讲了高阶函数的概念,并编写了一个简单的高阶函数: def add(x, y, f): return f(x) + f(y) 如果传入abs作为参数 ...

  8. java:redis(java代码操作redis,实体类mapper生成器(generator))

    1.redis_demo Maven  ItemMapper.xml: <?xml version="1.0" encoding="UTF-8" ?> ...

  9. 【JulyEdu-Python基础】第 1 课:入门基础

    一些学习资源的收集: 可汗学院 视频 公开课 Grossin 编程教室: 一个非常简单,对初学者非常友好的教程和在线联系 廖雪峰教程 书籍: Python核心编程: 这本书应该是最清楚.最深入全面的书 ...

  10. flask类装饰器

    from flask import Flask,request,views from functools import wraps app = Flask(__name__) #自定义登录装饰器 de ...