绑定到自定义依赖项属性 - 再次

时间:2012-12-19 16:27:20

标签: wpf xaml binding dependency-properties

好的,我知道。这已经被问了一百万次,但我仍然没有得到它。对不起。

任务:实现最简单的依赖属性,可以在xaml中使用:

<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>

我认为this答案非常接近。为了更好的可读性,我在这里复制了所有代码(主要来自上面的答案)。

<UserControl x:Class="Test.UserControls.MyUserControl1"
             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" 
             DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <!-- Text is being bound to outward representative property;
             Note the DataContext of the UserControl -->
        <TextBox Text="{Binding MyTextProperty}"/>
    </Grid>
</UserControl>

public partial class MyUserControl1 : UserControl
{
    // The dependency property which will be accessible on the UserControl
    public static readonly DependencyProperty MyTextPropertyProperty =
        DependencyProperty.Register("MyTextProperty", typeof(string), typeof(MyUserControl1), new UIPropertyMetadata(String.Empty));
    public string MyTextProperty
    {
        get { return (string)GetValue(MyTextPropertyProperty); }
        set { SetValue(MyTextPropertyProperty, value); }
    }

    public MyUserControl1()
    {
        InitializeComponent();
    }
}

这是我的MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:uc="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel Orientation="Vertical">
        <uc:MyUserControl1 MyTextProperty="my text goes here"/>
        <Button Click="ButtonBase_OnClick" Content="click"/>
    </StackPanel>
</Window>

到目前为止,一切正常。但是,我觉得这没有用。我需要的是

<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>

并且能够通过设置DataContext来改变这种情况(就像你在MVVM中一样)

所以我替换上面的行并添加我的代码如下:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        Text = "Initial Text";
        DataContext = this;
    }
    private string _Text;
    public string Text
    {
        get { return _Text; }
        set
        {
            if (value != _Text)
            {
                _Text = value;
                NotifyPropertyChanged("Text");
            }
        }
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        Text = "clicked";
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

无论是“初始文本”还是“点击”都不会显示......所以我的问题是如何实施部门。属性正确与

一起使用
<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>

?谢谢你帮助我。

1 个答案:

答案 0 :(得分:23)

Text属性位于 MainWindow DataContext,而非UserControl。

所以将此行<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>更改为:

<uc:MyUserControl1 MyTextProperty="{Binding Text, ElementName=MyMainWindow}"/>

这将告诉Binding您正在谈论位于MainWindow中的Text元素。当然,因为在这个例子中我使用了ElementName,你会想要命名你的窗口MyMainWindow ......

所以将它添加到您的MainWindow:

<Window  Name="MyMainWindow" ..... />

如果您不想命名窗口,可以像这样使用RelativeSource FindAncestor绑定:

<wpfApplication6:MyUserControl1 MyTextProperty="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"/>

在这两种方式中,您都要求在窗口的DataContext中找到名为“Text”的属性。