简体   繁体   English

在用户控件内绑定控件的属性

[英]Binding a property of a control within a user control

For the purpose of this question, I have defined a very simple user control: 出于这个问题的目的,我定义了一个非常简单的用户控件:

<UserControl x:Class="simpleUserControl.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Height="300" 
             Width="300">
     <Grid>
         <TextBox Name="TextBox1"/>
     </Grid>
 </UserControl>

I want the user (of the user control) to be able to set the 'Text' property of 'TextBox1', so I defined a property (named it 'text') that gets and sets TextBox1.Text: 我希望用户(用户控件的用户)能够设置'TextBox1'的'Text'属性,因此我定义了一个属性(命名为'text'),该属性获取并设置TextBox1.Text:

namespace simpleUserControl
{
    public partial class UserControl1 : UserControl
    {
        public string text
        {
            get { return TextBox1.Text; }
            set { TextBox1.Text = value; }
        }

        public static readonly DependencyProperty textProperty = DependencyProperty.Register("text", typeof(string), typeof(UserControl1));

        public UserControl1()
        {                       
            InitializeComponent();
        }
    }
}

Now, when using the user control , I want to bind this 'text' property to some string object: 现在,当使用用户控件时,我想将此'text'属性绑定到某些字符串对象:

 <Window x:Class="WpfApplication33.Window1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:simple_user_control="clr-namespace:simpleUserControl;assembly=simpleUserControl"
         Title="Window1" 
         Height="300" 
         Width="300" 
         Loaded="Window_Loaded">
    <Grid Name="MainGrid">
        <simple_user_control:UserControl1 Name="MyUserControl">
            <simple_user_control:UserControl1.text>
                <Binding Path="my_text"/>
            </simple_user_control:UserControl1.text>
        </simple_user_control:UserControl1>
    </Grid>
</Window>

and the code behind: 以及后面的代码:

namespace WpfApplication33
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        string my_text = "this is a text";
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            MainGrid.DataContext = this;
        }
    }
}

But that doesn't work for some reason... I don't understand why, because I have set the DataContext and put a reference to the user control... What am I doning wrong? 但这由于某些原因而行不通...我不明白为什么,因为我已经设置了DataContext并引用了用户控件...我在做什么错? (It is worth mentioning that when setting 'text' property directly like this: (值得一提的是,当直接像这样设置'text'属性时:

MyUserControl.text = "Another text";

everything works fine, and therefore I think that that the problem has something to do with the binding). 一切正常,因此我认为问题与绑定有关。

You don't have a property, you have a private member for my_text and WPF won't bind to it. 您没有属性,拥有my_text的私有成员,WPF不会绑定到该属性。

Try this: 尝试这个:

private string myText = "this is a text";
public string MyText
{
    get
    {
        return myText;
    }

    set
    {
        myText = value;
    }
}

And you should probably implement INotifyPropertyChanged in the setter, if you want to alter the text and display the changes automatically. 如果您要更改文本并自动显示更改,则可能应该在setter中实现INotifyPropertyChanged

You were right about implementing INotifyPropertyChanged , but There is still something missing. 您实现INotifyPropertyChanged是正确的,但仍然缺少一些东西。

The code of the main window now looks like this: 现在,主窗口的代码如下所示:

  public partial class MainWindow : Window, INotifyPropertyChanged
{
 public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    private string _my_text;
    string my_text
    {
        get { return _my_text; }
        set 
        { 
            _my_text = value;
            OnPropertyChanged("my_text");
        }
    }

    private void Window_Loaded_1(object sender, RoutedEventArgs e)
    {
        MainGrid.DataContext = this;
        MyUserControl.text = "This is a text";
        my_text = "Another text";  
    }
 }

And yet, the only text that appears is "This is a text" and not "Another text". 但是,出现的唯一文本是“这是一个文本”,而不是“另一个文本”。

What's wrong now? 现在怎么了

You haven't connected up the TextBox.Text property to your dependency property in the user control. 您尚未将TextBox.Text属性连接到用户控件中的依赖项属性。 Changes in the DependencyProperty text will be handled by WPF and won't actually go through your control's text property. WPF将处理DependencyProperty文本中的更改,而实际上不会通过控件的text属性。 You should define your control as follows to bind the TextBox.Text property to your dependency property: 您应该按照以下方式定义控件,以将TextBox.Text属性绑定到依赖项属性:

<UserControl x:Class="simpleUserControl.UserControl1"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Height="300" Width="300" x:Name="control">
 <Grid>
     <TextBox Name="TextBox1" Text="{Binding text, ElementName=control}"/>
 </Grid>
 </UserControl>

In the code-behind: 在后面的代码中:

namespace simpleUserControl
{
public partial class UserControl1 : UserControl
{
    public string text
    {
        get { return (string)GetValue(textProperty); }
        set { SetValue(textProperty, value); }
    }

    public static readonly DependencyProperty textProperty = DependencyProperty.Register("text", typeof(string), typeof(UserControl1));

    public UserControl1()
    {                       
        InitializeComponent();
    }
}
}

Then in your MainWindow you should be able to do this and it should work: 然后在您的MainWindow中,您应该可以执行此操作,并且应该可以正常工作:

private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
    MainGrid.DataContext = this;
    my_text = "This is a text";
    my_text = "Another text";  
}

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

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