【问题标题】:UserControl DataContext Binding用户控件数据上下文绑定
【发布时间】:2016-01-29 13:32:18
【问题描述】:

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

  • 我的主 WPF 应用程序包含一个 MainWindow + MainViewModel
  • 带有 UserControl 的 UserControl 库 (ConfigEditorView)
  • 带有用于 UserControl 的 ViewModel 的 UIProcess 类 (ConfigEditorViewModel)

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

首先我在我的 MainWindow 中设置 UserControl:

<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”,但它是空的。

我做错了什么?

【问题讨论】:

  • 您的 ConfEditModel 不会通知 UI 更改,因此您的 cel:ConfigEditorView 的 DataContext 不会更新
  • 谢谢@nkoniishvt 我在编码时没有考虑到这一点,但现在它可以正常工作了。

标签: c# wpf mvvm user-controls datacontext


【解决方案1】:

我给了你一个笼统的答案:

在“真实(您想与具有不同属性名称的不同视图模型一起使用的用户控件)”用户控件中,您只绑定到您自己的 DependencyProperties,然后您可以使用 ElementName 或 RelativeSource 绑定 并且您应该永远不要在 UserControl 中设置 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); }
    }

【讨论】:

    【解决方案2】:

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

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

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

    请注意,您必须实现接口并正确使用它。 This example says it's for 2010,但它工作正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-29
      • 1970-01-01
      • 2012-04-01
      • 1970-01-01
      相关资源
      最近更新 更多