开发者

Binding a property of a control within a user control

开发者 https://www.devze.com 2023-02-15 07:04 出处:网络
For the purpose of this question, I have defined a very simple user control: <UserControl x:Class=\"simpleUserControl.UserControl1\"

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:

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:

 <Window x:Class="WpfApplication33.Window1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xm开发者_运维知识库lns: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? (It is worth mentioning that when setting 'text' property directly like this:

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.

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.


You were right about implementing INotifyPropertyChanged, but There is still something missing.

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. Changes in the DependencyProperty text will be handled by WPF and won't actually go through your control's text property. You should define your control as follows to bind the TextBox.Text property to your dependency property:

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

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

精彩评论

暂无评论...
验证码 换一张
取 消