如何创建“正常”绑定的UserControl?

时间:2011-10-07 01:19:37

标签: c# silverlight binding user-controls

我会解释我的意思。

我们说我将TextBox包装到UserControl中并公开属性 Id 要绑定到此属性,它必须是Dependency属性。好的,这里我们去(注意愚蠢的舞蹈与OnIdChanged调用属性setter所以我们得到INotifyPropertyChanged工作):

public static readonly DependencyProperty IdProperty =
            DependencyProperty.RegisterAttached("Id", typeof(string), typeof(MyTextBox), new PropertyMetadata(OnIdChanged));

public string Id
        {
            get
            {
                return (string)GetValue(IdProperty);
            }

            set
            {
                this.SetValue(IdProperty, value);
                this.OnPropertyChanged("Id");
            }
        }

private static void OnIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as Lookup).Id = e.NewValue as string;
        }

所以,这似乎就是我所需要的。我创建另一个用户控件。删除MyTextBox:

    <Lookup:MyTextBox Id="{Binding Source={StaticResource DataContextProxy}, Path=DataSource.CurrentItem.DeviceId, Mode=TwoWay, NotifyOnValidationError=True}"/>

如您所见 - 我必须使用DataContextProxy。说实话,这对我来说有点神奇,我曾经做过一次并且在常规方式没有约束力的时候尝试过。我该如何编写用户控件代码,以便我可以像这样绑定它?

        <Lookup:MyTextBox Id="{Binding Path=CurrentItem.DeviceId, Mode=TwoWay, NotifyOnValidationError=True}"/>

这就是我可以将TextBox绑定到自定义文本旁边的方法,它可以按预期工作。秘密是什么?

修改

以下是2个截图。第一个展示了当我绑定到Lookup控件(自定义UserControl)时我获取的源代码 - 指向SELF

第二个 - 我的XAML中的下一个字段 - 是常规文本框,绑定到同一个CurrentItem但它来自我的ViewModel enter image description here enter image description here

编辑2

我想为什么DataContext指向UserControl本身。我想为什么但不明白为什么......

在初始化之后我的UserControl(查找)代码中我设置了this.DataContext =这样内部控件它绑定到内部属性。它以某种方式传播到父ViewModel。我将此代码更改为LayoutRoot.DataContext = this - 问题已解决。但我不明白为什么它会像这样,我仍然无法获得良好的物业路线..

1 个答案:

答案 0 :(得分:2)

我在I wrote some time ago的博文中介绍了这个问题。如果将UserControl的DataContext设置为自身,则不能再将其放在另一个UserControl或Window中,并期望它继承其父级的DataContext。这意味着您不能只将它放在视图中并指定视图模型的绑定。原因是您已阻止ViewModel DataContext的继承。 UserControl公开的任何属性都将其绑定Source设置为UserControl。

解决方案是将UserControl中的某些元素的DataContext设置为UserControl本身。通常,您可以设置UserControl的直接子项。