WPF之数据绑定Binding

WPF之Binding介绍

一、什么是数据绑定

请参考微软官方文档 数据绑定概述 - WPF .NET | Microsoft Learn

二、什么是DataContext

每个控件都有属于自己的DataContext,DataContext可以简单理解成每个控件的数据源,

如果未设置控件绑定的 DataContext 属性,则将检查父元素的 DataContext 属性,依此类

推,直到 XAML 对象树的根。如果父元素存在DataContext则该控件自动继承父控件的

DataContext。

三、如何设置DataContext

3.1、设置MainWindow的DataContext

5.1、数据源为自身

Binding Self表示绑定源为控件自身,比如如下

<TextBlock FontSize="16" Text="{Binding FontSize,RelativeSource={RelativeSource Self}}"/>

该段表示该TextBlock的Text绑定到自身的FontSize属性上,显示如下

5.2、通过ElementName设置数据源

<StackPanel Orientation="Vertical">
    <TextBox x:Name="TextBoxName" FontSize="22"/>
    <TextBlock x:Name="TextBlockName" Text="{Binding Text,ElementName=TextBoxName}"/>
</StackPanel>
this.TextBlockName.SetBinding(TextBlock.TextProperty,new Binding("Text"){
  Source=this.TextBoxName,
  Mode=BindingMode.OneWay,

5.3、通过TemplateBinding/TemplatedParent绑定

这两种方式主要是重写控件的ControlTemplate中指定,并且
Binding XXX,RelativeSource={RelativeSource TemplatedParent}
TemplateBinding XXX
参数如下自定义的控件Label的Style代码

<Style x:Key="LabelStyle1" TargetType="{x:Type Label}">
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Padding" Value="5"/>
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
        <Setter Property="VerticalContentAlignment" Value="Top"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Label}">
                    <Border
                        BorderBrush="{Binding BorderBrush,RelativeSource={RelativeSource TemplatedParent}}" 
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Background="{TemplateBinding Background}"
                        Padding="{TemplateBinding Padding}"
                        SnapsToDevicePixels="true">
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

5.3、通过AncestorType/AncestorLevel指定数据源

这是查找父控件来指定该子控件数据源,AncestorType表示父控件的类型,AncestorLevel表示向父控件查找的层级

<GroupBox Header="Binding AncestorType1">
                <GroupBox Header="Binding AncestorType2">
                    <TextBlock Text="{Binding Path=Header,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=GroupBox}}"/>
                </GroupBox>
            </GroupBox>
            <GroupBox Header="Binding AncestorLevelXXX1">
                <StackPanel Orientation="Vertical">
                    <GroupBox Header="Binding AncestorLevelXXX2">
                        <TextBlock Text="{Binding Path=Header,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=GroupBox,AncestorLevel=2}}"/>
                    </GroupBox>
                </StackPanel>
            </GroupBox>

该段代码显示结果如下

这个表示数据源可以指定多个,如下代码

<StackPanel Orientation="Vertical">
                    <Slider x:Name="MultiSliderName" Maximum="100" Minimum="0" ToolTip="{Binding Value,RelativeSource={RelativeSource Self}}"/>
                    <TextBlock Foreground="{StaticResource PrimaryBursh}">
                        <TextBlock.Text>
                            <MultiBinding Converter="{StaticResource ValueMaxConverter}">
                                <Binding Path="Value" ElementName="MultiSliderName"/>
                                <Binding Path="Maximum" ElementName="MultiSliderName"/>
                            </MultiBinding>
                        </TextBlock.Text>
                    </TextBlock>
                </StackPanel>
该示例指定TextBlock的Text属性来源于Slider 中的两个属性Value和Maximum,通过这两个属性来指定TextBolck的显示,效果如下