WPF桌面端开发-数据绑定(Binding)

按名称绑定

1
2
3
4
<Rectangle Fill="Red" Name="rectangle"
Height="100" Stroke="Black"
Canvas.Top="100" Canvas.Left="100"
Width="{Binding ElementName=rectangle,Path=Height}"/>

或者

1
2
3
4
<StackPanel>
<TextBox x:Name="textBox1" Text="{Binding Path=Value,ElementName=slider1}"/>
<Slider x:Name="slider1" Maximum="100" Minimum="0"/>
</StackPanel>

绑定自身属性

1
2
3
<Rectangle Fill="Red" Height="100"
Stroke="Black"
Width="{Binding RelativeSource={RelativeSource Self},Path=Height}"/>

绑定祖先元素属性

如果想让图片上下填充满,左右等比自适应,可以使用下面的方式实现:

1
2
3
4
5
6
7
8
9
10
<Border BorderBrush="#434343" BorderThickness="1">
<Grid>
<Image
Height="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Source="{Binding}"
Stretch="Uniform" />
</Grid>
</Border>

这里

设置图片的高度后缩放方式设置为Uniform,这样图片高度就固定了,宽度会等比缩放,再设置水平居中,就实现了这个效果。

其中

RelativeSource={RelativeSource AncestorType={x:Type Grid}} 是用来指定查找最近类型为Grid的祖先元素。

TemplatedParent

此模式允许将给定的 ControlTemplate 属性绑定到应用 ControlTemplate 的控件的属性。为了更好地理解这里的问题,下面是一个示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<Window.Resources>
<ControlTemplate x:Key="ZTemplate">
<Canvas>
<Canvas.RenderTransform>
<RotateTransform Angle="20" />
</Canvas.RenderTransform>
<Ellipse
Width="150"
Height="100"
Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}" />
<ContentPresenter Margin="35" Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
</Canvas>
</ControlTemplate>
</Window.Resources>
<Canvas Name="Parent0">
<Button
Canvas.Left="0"
Canvas.Top="0"
Width="0"
Height="0"
Margin="50"
Template="{StaticResource ZTemplate}">
<TextBlock FontSize="22">Click me</TextBlock>
</Button>
</Canvas>

如果我想应用给定控件的属性到它的控件模板,那么我可以使用TemplatedParent模式。

TemplateBinding一般用于绑定控件模板内的属性,而TemplatedParent用于在控件模板内访问父元素的属性。

TemplateBinding

在 WPF 中, TemplateBinding 用于在控件模板中绑定到控件的属性。这可以让模板基于控件的属性值更改其视觉体验。

这里是一个简单示例:MainWindow.xaml

1
2
3
4
5
6
7
8
9
10
11
12

<Window x:Class="TemplateBindingDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TemplateBindingDemo"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:MyButton Template="{StaticResource MyButtonTemplate}"
Background="Blue"
Content="Button" />
</Grid>
</Window>

MyButton.xaml

1
2
3
4
5
6
7
8
9
10
11
12
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TemplateBindingDemo">

<ControlTemplate x:Key="MyButtonTemplate" TargetType="local:MyButton">
<Border BorderBrush="Black" BorderThickness="1"
Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
</ControlTemplate>
</ResourceDictionary>

MyButton.cs

1
2
3
4
public class MyButton : Button 
{
// ...
}

在这里,我们为 MyButton 定义了一个 ControlTemplate。

在模板中,我们使用 {TemplateBinding Background}{TemplateBinding Content} 来绑定到控件的 BackgroundContent 属性。
所以模板会随着控件属性的改变而改变。

运行这个示例,你会看到一个蓝色的按钮,上面写着 “Button”。如果你改变 MyButtonBackgroundContent 属性,模板会相应更新。