Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding UserControl to its own dependencyProperty doesn't work

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:

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

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.

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:

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.

Thanks

like image 247
Nick Williams Avatar asked Dec 08 '22 14:12

Nick Williams


1 Answers

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:Name of your UserControl, and use that in the binding.

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

like image 192
Will Eddins Avatar answered Dec 11 '22 09:12

Will Eddins