wpf 将 UserControl 绑定到它自己的 dependencyProperty 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17955833/
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-13 09:19:19  来源:igfitidea点击:

Binding UserControl to its own dependencyProperty doesn't work

c#wpfdata-bindingmvvmuser-controls

提问by Nick Williams

Im having a problem where I can't create a User Control which uses properties of an custom object when the parent has set that object to data bind.

我遇到了一个问题,当父对象已设置为数据绑定时,我无法创建使用自定义对象的属性的用户控件。

To try an explain what I mean here is the code. Custom object:

尝试解释一下我的意思是代码。自定义对象:

public class MyObj
{
    public string Text { get; set; }

    public MyObj(string text)
    {
        Text = text;
    }
}

User Control Code Behind:

背后的用户控制代码:

/// <summary>
/// Interaction logic for MyControl.xaml
/// </summary>
public partial class MyControl : UserControl
{
    public static readonly DependencyProperty ObjectProperty =
        DependencyProperty.Register("Object", typeof (MyObj), typeof (MyControl), new PropertyMetadata(default(MyObj)));

    public MyObj Object
    {
        get { return (MyObj) GetValue(ObjectProperty); }
        set { SetValue(ObjectProperty, value); }
    }

    public MyControl()
    {
        InitializeComponent();
    }
}

User control XAML:

用户控制 XAML:

<UserControl x:Class="Test.MyControl"
         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" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<TextBlock Text="{Binding Object.Text}"/>

So all I expect is for MyControl to display a TextBlock with text showing whatever string is in MyObj.Text;

所以我所期望的只是让 MyControl 显示一个带有文本的 TextBlock,显示 MyObj.Text 中的任何字符串;

If I add the control in code, without any bindings, then this works Okay e.g.

如果我在代码中添加控件,没有任何绑定,那么这可以正常工作,例如

MyControl myControl = new MyControl(){ Object = new MyObj("Hello World!") };
grid.Children.Add(myControl);

However if I try to use data binding this doesn't display anything, here is the code for MainWindow.

但是,如果我尝试使用数据绑定,则不会显示任何内容,这是 MainWindow 的代码。

CodeBehind:

代码隐藏:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private MyObj _Object;
    public MyObj Object
    {
        get { return _Object; }
        set
        {
            _Object = value;
            OnPropertyChanged("Object");
        }
    }

    public MainWindow()
    {
        InitializeComponent();

        Object = new MyObj("HELLO");
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML:

XAML:

Could anyone point me in the right direction, I guess it's something to do with using relative source binding on the UserControl but I'm not sure.

谁能指出我正确的方向,我想这与在 UserControl 上使用相对源绑定有关,但我不确定。

Thanks

谢谢

回答by Will Eddins

I've personally never used a relative self binding on a UserControl, so I'm unsure if it works. You may try setting the x:Nameof your UserControl, and use that in the binding.

我个人从未在 UserControl 上使用过相对自绑定,所以我不确定它是否有效。您可以尝试设置x:Name你的UserControl,而且使用的绑定。

<UserControl x:Class="Test.MyControl"
             ...
             x:Name="window">
    <TextBlock Text="{Binding ElementName=window, Path=Object.Text}"/>
</UserControl>

Note that if a data-binding fails to bind at runtime, you should also see a related error message in the Output window.

请注意,如果数据绑定在运行时无法绑定,您还应该在“输出”窗口中看到相关的错误消息。

回答by Akash Gutha

it's been a long time .. but since there is a new technique i would like to post it here.

已经很长时间了..但是由于有一项新技术,我想在这里发布它。

Compiled Time Binding : this is a new type of binding introduced with windows 10. this binding has a lot of performance benefits classic binding.

编译时绑定:这是 Windows 10 中引入的一种新型绑定。此绑定具有许多经典绑定的性能优势。

And the extra benefit you need not set any DataContextthe Page or Control itself is the DataContextyou can bind to anything in the page or Control

您无需设置任何DataContext页面或控件本身的额外好处是您可以绑定到页面或控件中的任何内容的DataContext

<UserControl x:Class="Test.MyControl"
             ...
             x:Name="window">
    <TextBlock Text="{x:Bind Object.Text}"/>
</UserControl>

But does this work perfectly as you have imagined .. No!! not as u guessed. and there is an answer to it .

但是这是否像您想象的那样完美地工作..不!不像你猜的那样。并且有一个答案。

Compiled time binding are by default set to OneTimeas opposed to classic bindings that are se to OneWay.

编译时绑定的默认设置为一次性的,而不是传统的绑定是本身对于单向

so you need to explicitly set the mode to OneWayto ensure the value always updates.

因此您需要将模式显式设置为OneWay以确保该值始终更新。

<UserControl x:Class="Test.MyControl"
             ...
             x:Name="window">
    <TextBlock Text="{x:Bind Object.Text,Mode=OneWay}"/>
</UserControl>