简体   繁体   English

将自定义类型属性绑定到自定义控件

[英]Bind a custom type property to a custom control

I am trying to bind to a user control a property of a custom type (in our exemple, let's call it DataContextOne ). 我正在尝试将自定义类型的属性绑定到用户控件(在我们的示例中,我们将其称为DataContextOne )。 This custom type is composed of two strings. 此自定义类型由两个字符串组成。

I then have a user control to which I want to bind this custom type. 然后,我有一个要将此自定义类型绑定到的用户控件。

The weird thing is that if I put in my control 2 string properties and then try to bind each string from my custom type, it worked. 奇怪的是,如果我放入控件2的字符串属性,然后尝试从我的自定义类型绑定每个字符串,那么它就起作用了。 But when I create just a DataContextOne property in my Custom Control and try to bind to it, nothing happens (= null in the user control). 但是,当我在自定义控件中仅创建一个DataContextOne属性并尝试绑定到它时,什么也没发生(在用户控件中为null)。

Here is my code 这是我的代码

DataContextOne DataContextOne

public class DataContextOne : INotifyPropertyChanged
{
    protected virtual void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

    }

    public event PropertyChangedEventHandler PropertyChanged;

    private string _title;
    public string Title 
    {
        get { return _title; }
        set
        {
            if (_title != value)
            {
                _title = value;
                TitleModified = _title + " modified";
                RaisePropertyChanged("Title");
            }
        }
    }

    private string _titlemodified;
    public string TitleModified
    {
        get { return _titlemodified; }
        set
        {
            if (_titlemodified != value)
            {
                _titlemodified = value;
                RaisePropertyChanged("TitleModified");
            }
        }

    }
}

Binding that works 绑定有效

UserControl 用户控件

public partial class MyUserControl : UserControl
{

    public MyUserControl()
    {
        InitializeComponent();
        (Content as FrameworkElement).DataContext = this;
    }

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
            "Text",
            typeof(string),
            typeof(MyUserControl),
            null);

    public string TextModified
    {
        get { return (string)GetValue(TextModifiedProperty); }
        set { SetValue(TextModifiedProperty, value); }
    }

    public static readonly DependencyProperty TextModifiedProperty = DependencyProperty.Register(
            "TextModified",
            typeof(string),
            typeof(MyUserControl),
            null);
}

Main Window 主视窗

code behind 背后的代码

public partial class MainWindow : Window
{
    Random Rnd = new Random();
    DataContextOne dtone = new DataContextOne();

    public MainWindow()
    {
        InitializeComponent();
        dtone.Title = Rnd.Next().ToString();
        DataContext = dtone;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        dtone.Title = Rnd.Next().ToString();
    }
}

xaml: XAML:

<local:MyUserControl Grid.Row="1" Text="{Binding Title, UpdateSourceTrigger=PropertyChanged}" TextModified="{Binding TitleModified, UpdateSourceTrigger=PropertyChanged}"/>

Binding that doesn't work 绑定无效

User Control 用户控制

public partial class MyUserControl : UserControl
{

    public MyUserControl()
    {
        InitializeComponent();
        (Content as FrameworkElement).DataContext = this;
    }

    public DataContextOne dtone 
    {
        get { return (DataContextOne)GetValue(dtoneProperty); }
        set { SetValue(dtoneProperty, value); }
    }

    public static readonly DependencyProperty dtoneProperty = DependencyProperty.Register(
            "dtone",
            typeof(DataContextOne),
            typeof(MyUserControl),
            null);

}

Main Window 主视窗

Code Behind (note that I bind this ) 后面的代码(注意,我结合this

public partial class MainWindow : Window
{
    Random Rnd = new Random();
    DataContextOne dtone = new DataContextOne();

    public MainWindow()
    {
        InitializeComponent();
        dtone.Title = Rnd.Next().ToString();
        DataContext = this;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        dtone.Title = Rnd.Next().ToString();
    }
}

xaml XAML

<local:MyUserControl Grid.Row="1" dtone="{Binding dtone, UpdateSourceTrigger=PropertyChanged}" Margin="0,31,200,169"/>

I don't understand what is missing. 我不明白缺少了什么。 For me it is the same thing with just a custom type that encapsulate the strings on the second version, so why it doesn't work? 对我来说,只有一个自定义类型封装了第二个版本中的字符串,这是同一件事,那么为什么它不起作用?

{Binding dtone} tries to bind to dtone property of DataContext , which is MainWindow . {Binding dtone}尝试绑定到DataContext dtone属性,即MainWindow There is no dtone property in MainWindow class, only a private field, and you cannot bind to fields. MainWindow类中没有dtone属性,只有一个私有字段,并且您无法绑定到字段。

Possible solutions: 可能的解决方案:

  • make dtone a property 使dtone成为属性
  • or change DataContext = this to DataContext = dtone and {Binding dtone} to {Binding} 或将DataContext = this更改为DataContext = dtone并将{Binding dtone}更改为{Binding}

Update 更新

Probably unrelated, but there seems to be no reason to have a dtone property in MyUserControl . 可能无关,但是似乎没有理由在MyUserControl具有dtone属性。 Why not simple 为什么不简单

<local:MyUserControl Grid.Row="1" DataContext="{Binding dtone}" />

without trying to set DataContext manually in MyUserControl constructor? 没有尝试在MyUserControl构造函数中手动设置DataContext

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM