用户控件数据上下文绑定

本文关键字:绑定 上下文 数据 控件 用户 | 更新日期: 2023-09-27 18:32:23

我的解决方案中有三个项目:

  • 我的主要 WPF 应用程序包含一个 MainWindow + MainViewModel
  • 用户控件库与用户控件 (ConfigEditorView
  • 具有 UserControl 视图模型的 UIProcess 类 (ConfigEditorViewModel

在我的 MainWindow 中,我想将 UserControl 与 UIProcess 的 ViewModel 一起使用。

首先,我在主窗口中设置用户控件:

<TabItem Header="Editor">
   <Grid>
     <cel:ConfigEditorView DataContext="{Binding ConfEditModel, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
   </Grid>
</TabItem>

我不知道我在这里需要哪些属性,所以我把它们放在一起,但它仍然不起作用。

然后我在我的 MainViewModel 中设置了这个:

public ConfigEditorViewModel ConfEditModel { get; set; }

使用绑定到按钮的简单方法:

private void doSomething()
{
    ConfEditModel = new ConfigEditorViewModel("Hello World");
}

我的ConfigEditorViewModel基本上看起来像这样:

public class ConfigEditorViewModel : ViewModelBase
{
    private string _Description;
    public string Description
    {
        get
        {
            return _Description;
        }
        set
        {
            _Description = value;
            base.RaisePropertyChanged();
        }
    }
    public ConfigEditorViewModel(string t)
    {
        Description = t;
    }
}

说明绑定到我的用户控件中的文本框。

<TextBox Grid.Row="1" Grid.Column="1" Margin="0,0,0,10" Text="{Binding Description}"/>

当我启动应用程序并单击按钮时,文本框应包含"Hello World",但它是空的。

我做错了什么?

用户控件数据上下文绑定

我给了你一个大致的答案:

在"real(要与具有不同属性名称的不同视图模型一起使用的用户控件)"用户控件中,您仅绑定到您自己的依赖项属性,并且使用 ElementName 或 RelativeSource 绑定执行此操作,并且永远不应在用户控件中设置 DataContext

 <UserControl x:Name="myRealUC" x:class="MyUserControl">
   <TextBox Text="{Binding ElementName=myRealUC, Path=MyOwnDPIDeclaredInMyUc, Path=TwoWay}"/>
 <UserControl>

如果这样做,您可以在任何视图中轻松使用此用户控件,例如:

<myControls:MyUserControl MyOwnDPIDeclaredInMyUc="{Binding MyPropertyInMyViewmodel}"/>

为了完整起见:依赖属性

    public readonly static DependencyProperty MyOwnDPIDeclaredInMyUcProperty = DependencyProperty.Register(
    "MyOwnDPIDeclaredInMyUc", typeof(string), typeof(MyUserControl), new PropertyMetadata(""));
    public bool MyOwnDPIDeclaredInMyUc
    {
        get { return (string)GetValue(MyOwnDPIDeclaredInMyUcProperty); }
        set { SetValue(MyOwnDPIDeclaredInMyUcProperty, value); }
    }

您的视图模型(以及可选的模型)需要实现 INotifyPropertyChanged。

绑定不是魔法。 没有内置机制允许在普通旧属性的值更改时通知代码。 您必须轮询它才能检查是否发生了更改,这在性能方面非常糟糕。

因此,绑定将查看它们绑定的对象,并查看它们是否实现了 INotifyPropertyChanged,如果是,则将订阅 PropertyChanged 事件。 这样,当您更改属性并触发事件时,绑定将收到通知并更新 UI。

请注意,您必须实现接口并正确使用它。 此示例表示它是 2010 年的,但它工作正常。