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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13956767/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:37:28  来源:igfitidea点击:

Binding to custom dependency property - again

wpfxamlbindingdependency-properties

提问by Martin Booka Weser

OK, i know. This has been asked literally one million times, but i still don't get it. Sorry for that.

好的,我知道。这实际上已经被问了一百万次,但我仍然不明白。对不起。

The task: implement the simplest Dependency Property ever, which can be used in xaml like that:

任务:实现有史以来最简单的依赖属性,可以像这样在 xaml 中使用:

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

I think that thisanswer is quite close. For better readability i copy all my code here (mostly from that answer above).

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

<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>

and

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();
    }
}

And this is my MainWindow.xaml

这是我的 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>

So far, everything works. However, i find this quite not usefull. What i'd need is

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

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

and being able to change this by setting a DataContext(as you usually do in MVVM)

并且能够通过设置 a 来改变它DataContext(就像你通常在 MVVM 中所做的那样)

So i replace the line as above and add my code behind as follows:

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

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));
        }
    }
}

Neither the "initial Text" nor the "clicked" is displayed... ever. So my question is how to implement a dept. property correctly to be used with

“初始文本”和“点击”都没有显示......永远。所以我的问题是如何实现一个部门。正确使用的属性

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

? Thanks for helping me out.

? 谢谢你的协助。

回答by Blachshma

The Textproperty is located on the DataContextof the MainWindownot of the UserControl.

Text物业位于DataContext中的主窗口不是用户控件的。

So change this line <uc:MyUserControl1 MyTextProperty="{Binding Text}"/>into this:

所以把这一行<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>改成这样:

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

Which will tell the Binding that you're talking about the Text element located in you MainWindow. Of course, since in this example I used ElementName, you're going to want to nameyour window MyMainWindow...

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

So add this to your MainWindow:

因此,将其添加到您的 MainWindow:

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

If you rather not name your window, you can use the RelativeSource FindAncestor binding like this:

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

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

In both ways, you are asking to find the property named 'Text' in the DataContext of the window.

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