FlyingStreudel
FlyingStreudel

Reputation: 4474

WPF Databinding a Custom Control

So I've spent about two hours pounding my head against the desk trying everything I can think of to bind to a property on a custom control and none of it works. If I have something like this:

<Grid Name="Form1">
    <mine:SomeControl MyProp="{Binding ElementName=Form1, Path=DataContext.Enable}"/>
    <Button Click="toggleEnabled_Click"/>
</Grid>
public class TestPage : Page
{
    private TestForm _form;

    public TestPage()
    {
        InitializeComponent();
        _form = new TestForm();
        Form1.DataContext = _form;
    }

    public void toggleEnabled_Click(object sender, RoutedEventArgs e)
    {
        _form.Enable = !_form.Enable;
    }
}

TestForm looks like:

public class TestForm
{
    private bool _enable;

    public event PropertyChangedEventHandler PropertyChanged;

    public bool Enable
    {
       get { return _enable; }
       set { _enable = value; OnPropertyChanged("Enable"); }
    }

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

And my control looks like:

<UserControl>
    <TextBox Name="TestBox"/>
</UserControl>
public class SomeControl : UserControl
{
    public static readonly DependencyProperty MyPropProperty =
        DependencyProperty.Register("MyProp", typeof(bool), typeof(SomeControl));

    public bool MyProp
    {
        get { return (bool)GetValue(MyPropProperty); }
        set { SetValue(MyPropProperty, value); }
    }

    public SomeControl()
    {
        InitializeComponent();
        DependencyPropertyDescriptor.FromProperty(MyPropProperty)
            .AddValueChanged(this, Enable);
    }

    public void Enable(object sender, EventArgs e)
    {
        TestBox.IsEnabled = (bool)GetValue(MyPropProperty);
    }
}

Absolutely nothing happens when I click the toggle button. If I put a breakpoint inside of the Enable callback it is never hit, whats the deal?

Upvotes: 0

Views: 1440

Answers (1)

brunnerh
brunnerh

Reputation: 185553

If the Enabled method does not do any more than setting the propertou you could drop it and bind the TextBox.IsEnabled directly:

<UserControl Name="control">
    <TextBox IsEnabled="{Binding MyProp, ElementName=control}"/>
</UserControl>

If you want to keep such a method you should register a property changed callback via UIPropertyMetadata for the dependency property.


Also this binding is redundant:

{Binding ElementName=Form1, Path=DataContext.Enable}

The DataContext is inherited (if you don't set it in the UserControl (which you should never do!)), so you can just use:

{Binding Enable}

Further if there is trouble with any of the bindings: There are ways to debug them.

Upvotes: 2

Related Questions