【问题标题】:WPF Databinding a Custom ControlWPF 数据绑定自定义控件
【发布时间】:2012-07-25 03:39:41
【问题描述】:

因此,我花了大约两个小时将头撞在桌子上,尝试了所有我能想到的绑定到自定义控件上的属性的方法,但都不起作用。如果我有这样的事情:

<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 看起来像:

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

我的控件看起来像:

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

当我单击切换按钮时,绝对没有任何反应。如果我在 Enable 回调中设置断点,它永远不会被命中,有什么关系?

【问题讨论】:

    标签: wpf data-binding custom-controls


    【解决方案1】:

    如果Enabled 方法除了设置属性之外没有任何作用,您可以删除它并直接绑定TextBox.IsEnabled

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

    如果你想保留这样的方法,你应该通过UIPropertyMetadata为依赖属性注册一个属性更改回调。


    这个绑定也是多余的:

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

    DataContext 是继承的(如果你没有在UserControl 中设置它(你永远不应该这样做!)),所以你可以使用:

    {Binding Enable}
    

    如果任何绑定有问题,请进一步说明:There are ways to debug them

    【讨论】:

    • 我的印象是DependencyPropertyDescriptor.FromProperty(MyPropProperty) .AddValueChanged(this, Enable); 会导致Enable 在该依赖属性的任何更改上被调用?此外,这是对我实际所做的事情的粗略简化。它只是充分代表了问题。
    • @FlyingStreudel:哦,我扫描了您的代码以查找任何呼叫,但错过了您将其作为参考传递。不要为此使用描述符,在注册 DP 时添加属性更改回调。 (使用各自的metadata constructor)。
    • 那是静态的吗?它如何引用当前实例上的控件?
    • @FlyingStreudel:当前实例作为第一个参数传递给属性更改回调。如果您需要使用示例,可​​以搜索 SO 或查看this
    • 如果你更新你的答案以反映我可以接受的 cmets
    猜你喜欢
    • 2015-07-07
    • 1970-01-01
    • 2013-06-14
    • 1970-01-01
    • 2015-06-03
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 2011-08-06
    相关资源
    最近更新 更多