WPF 用户控件UserControl 依赖属性绑定

  • A+
所属分类:WPF
 public string Text
{
    get { return (string)GetValue(TextProperty); }
    set { SetValue(TextProperty, value); }
}

// Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =DependencyProperty.Register("Text", typeof(string), typeof(UserControl1));
<UserControl x:Class="WpfApp3.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp3"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800" x:Name="uc">
    <StackPanel>
        <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:UserControl1},Path=Text}"></TextBlock>
        <TextBlock Text="{Binding ElementName=uc,Path=Text}"></TextBlock>
        <!--错误的绑定方式-->
        <!--<TextBlock Text="{Binding Text}"></TextBlock>-->
    </StackPanel>
</UserControl>
探究为什么

1.先给窗体设置一下DataContext,很简单的设置了一个对象。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new Student() { Name = "Body",Sex = "Male",Age = 18};
    }

}

public class Student { 
    public string Name { get; set; }

    public string Sex { get; set; }

    public int Age { get; set; }
}

2.在Xaml添加一个Lable,给Content属性添加绑定

<StackPanel>
    <Label x:Name="LableInstance" Content="{Binding}" ></Label>
</StackPanel>
  • 运行后很简单看出 Content绑定结果是自身的DataContext(为什么不是父级的,可以自己单独给Label设置一个和父级不一样DataContext,我就不演示了)。而且它的DataContext继承了父级的DataContext。StackPanel的DataContext自然而然也是这个。
    > 源码里面也定义了DataConetxt依赖属性,由子元素继承FrameworkPropertyMetadataOptions.Inherits
    > DataContextProperty = DependencyProperty.Register("DataContext", typeof(object), _typeofThis, new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, OnDataContextChanged));

我们不难发现用户控件的DataContext是继承于父级的。用户控件里面的元素也是继承用户控件的DataContext,所以是没办法用简单的Binding Path 来绑定到依赖属性的。
如果不喜欢写那么一大串的绑定,可以用模板来。用TemplateBinding 是直接绑定到控件的依赖属性上的。

<UserControl x:Class="WpfApp3.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp3"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <Style TargetType="local:UserControl1">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:UserControl1">
                        <TextBlock Text="{TemplateBinding Text}"></TextBlock>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
</UserControl>

PS:使用模板的话,建议直接使用定义自定义控件。

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: