【问题标题】:Binding UserControl to its own dependencyProperty doesn't work将 UserControl 绑定到它自己的 dependencyProperty 不起作用
【发布时间】:2013-07-30 19:35:24
【问题描述】:

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

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

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

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

用户控制代码背后:

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

用户控制 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}"/>

所以我只希望 MyControl 显示一个 TextBlock,其中的文本显示 MyObj.Text 中的任何字符串;

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

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

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

代码隐藏:

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:

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

谢谢

【问题讨论】:

    标签: c# wpf data-binding mvvm user-controls


    【解决方案1】:

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

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

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

    【讨论】:

    • 啊,完美,效果很好。在我从现在开始将它提交到内存之前,我从未使用过 ElementName。谢谢威尔
    【解决方案2】:

    已经很久了..但是由于有一种新技术我想在这里发布。

    Compiled Time Binding :这是 Windows 10 引入的一种新型绑定。这种绑定具有很多性能优势经典绑定。

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

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

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

    编译时间绑定默认设置为 OneTime,而经典绑定默认设置为 OneWay

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

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

    【讨论】:

      猜你喜欢
      • 2018-12-07
      • 1970-01-01
      • 2014-03-29
      • 2012-06-06
      • 2013-06-03
      • 2013-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多