WPF之ElementName,Source,RelativeSource绑定🔥
在WPF(Windows Presentation Foundation)中,ElementName,Source和RelativeSource是用于在XAML中进行数据绑定的重要属性和对象。
# ElementName
ElementName属性允许你将数据绑定目标设置为XAML中具有指定名称的另一个元素。你可以使用该属性来引用XAML中同一命名范围内的元素,以便在数据绑定中使用它们。这个属性通常用于在不同控件之间进行数据绑定。
<TextBox x:Name="textBox1" Text="{Binding TextValue}" />
<Label Content="{Binding Text, ElementName=textBox1}" />
2
# Source
Source属性允许你直接指定数据绑定的源对象实例。通常用于当你知道要绑定的对象的实例时,你可以直接使用该属性。这个属性不仅可以用于绑定到数据对象,也可以用于绑定到资源对象。
# 1、静态成员或属性
你可以使用 x:Static 扩展来指定一个静态成员或属性作为数据绑定的源。
<TextBox Text="{Binding Path=Name}" Source="{x:Static local:Person.DefaultPerson}" />
在这里,local:Person.DefaultPerson 表示引用了Person类的 DefaultPerson 静态属性作为数据绑定的源。因此,TextBox 的文本内容将根据Person.DefaultPerson 的值来动态显示。其文本内容通过数据绑定与 Person.DefaultPerson 的 Name 属性关联起来,使得 TextBox 的文本内容能够动态地显示 Person.DefaultPerson 的名字。
# 2、命名资源
你可以使用 {StaticResource} 或 {DynamicResource} 扩展来引用命名资源,其中 {StaticResource} 用于引用静态资源,而 {DynamicResource} 用于引用动态资源。
<TextBox Text="{Binding Path=Name}" Source="{StaticResource DefaultPerson}" />
在这个示例中,DefaultPerson 是一个在 XAML 中命名的静态资源。
# 3、常量值
如果你希望指定一个常量值作为数据绑定的源,你可以直接在大括号中写入常量值。
<TextBox Text="{Binding Path=Name}" Source="{x:Static local:Constants.DefaultPerson}" />
在这个示例中,Constants.DefaultPerson 可以是一个常量值,它作为数据绑定的源。
# 4、静态方法
有时你可能需要调用一个静态方法来获取数据绑定的源,你可以使用 {x:Static} 扩展来调用静态方法。
<TextBox Text="{Binding Path=Name}" Source="{x:Static local:Utility.GetDefaultPerson}" />
在这个示例中,Utility.GetDefaultPerson 表示调用 Utility 类的 GetDefaultPerson 静态方法,该方法返回数据绑定的源。
# RelativeSource
RelativeSource 是 WPF 中用于相对于当前元素查找绑定源的属性。它提供了一种动态的绑定方式,可以相对于当前元素的父级、祖先、兄弟等来确定绑定源。以下是 RelativeSource 的几种常见用法:
# 1、Self
用于将数据绑定的源设置为当前元素本身。
<TextBox Text="{Binding Path=Name, RelativeSource={RelativeSource Self}}" />
在这个示例中,TextBox 的 Text 属性通过数据绑定与自身的 Name 属性关联起来。
# 2、AncestorType
用于相对于当前元素查找指定类型的祖先元素,并将其作为数据绑定的源。
<TextBox Text="{Binding DataContext.Name, RelativeSource={RelativeSource AncestorType=Window}}" />
在这个示例中,TextBox 的 Text 属性通过数据绑定与其所在的 Window 元素的 DataContext 中的 Name 属性关联起来。
# 3、AncestorLevel
用于指定相对于当前元素的第几级祖先元素,并将其作为数据绑定的源。
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:YourNamespace"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<TextBox Text="{Binding Name}" />
<StackPanel>
<TextBox Text="{Binding DataContext.Name, RelativeSource={RelativeSource AncestorLevel=2}}" />
</StackPanel>
</StackPanel>
</Window>
2
3
4
5
6
7
8
9
10
11
12
在这个示例中,我们在 MainWindow 的 StackPanel 中嵌套了另一个 StackPanel。第一个 StackPanel 的 DataContext 是 Person 对象,因此第一个 TextBox 直接绑定到 Person 对象的 Name 属性。 第二个 TextBox 使用 AncestorLevel=2 来指定相对于当前元素的第二级祖先元素,即 MainWindow。这样,它就能访问 MainWindow 的 DataContext 中的 Person 对象的 Name 属性。 通过这种方式,我们可以使用 AncestorLevel 来访问位于嵌套结构中较远祖先元素的数据。
# 4、TemplatedParent
用于将数据绑定的源设置为控件模板中的父级元素(即使用该模板的控件)。
<Style TargetType="local:MyButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyButton">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<TextBlock Text="{TemplateBinding Content}"
Foreground="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="textBlock" Property="Foreground" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
在这个示例中,我们定义了一个名为 MyButton 的自定义按钮控件,它的模板中包含一个 TextBlock 控件来显示按钮的文本。在 TextBlock 的 Foreground 属性中,我们使用了 TemplatedParent 来绑定到 MyButton 控件的 Foreground 属性,以便按钮的文本颜色能够继承按钮的前景色。 然后,我们使用 ControlTemplate.Triggers 来定义一个触发器,在按钮的 IsMouseOver 属性为 True 时,将 TextBlock 控件的 Foreground 属性设置为红色,实现了按钮悬停时文本颜色变为红色的效果。