【问题标题】:Binding ViewModel to ContentControl as its DataContext将 ViewModel 绑定到 ContentControl 作为其 DataContext
【发布时间】:2012-07-19 23:24:26
【问题描述】:

我想在按钮单击时更改用户控件(我不会在这里复杂化,所以我只会提到重要的部分)。所以想法是将这些 UserControls 的 ViewModels 绑定到 ContentControl,然后使用 DataTemplates 将它们关联起来。 代码如下:

<Window x:Class="Project.MainWindow">
<Window.Resources>
    <DataTemplate DataType="{x:Type UserControl:ViewUserControlViewModel}" >
        <UserControl:ViewUserControl/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type UserControl:EditUserControlViewModel}" >
        <UserControl:EditUserControl/>
    </DataTemplate>
</Window.Resources>
<Grid>
    <ContentControl DataContext="{Binding UserControlViewModel}" />
    <Button Content="View" Click="ChangeToView()"/>
    <Button Content="Edit" Click="ChangeToEdit()"/>
</Grid>
</Window>

视图模型:

public class MainWindowViewModel : DependencyObject
{
    public DependencyObject UserControlViewModel
    {
        get { return (DependencyObject)GetValue(UserControlViewModelProperty); }
        set { SetValue(UserControlViewModelProperty, value); }
    }
    public static readonly DependencyProperty UserControlViewModelProperty = 
           DependencyProperty.Register("UserControlViewModel", typeof(DependencyObject), typeof(MainWindowViewModel), new PropertyMetadata());

    public MainWindowViewModel()
    {
        UserControlViewModel = new EditUserControlViewModel();
    }
}

但是有一个问题。当我开始项目时,我只看到按钮,但看不到任何用户控件。我做错了什么?

【问题讨论】:

  • 这是错字吗?您注册 userControlViewModel 但绑定到 UserControlViewModel。
  • 是的,这是一个错字。我现在更正了:)

标签: c# wpf mvvm


【解决方案1】:

如果您的 Window.DataContext 正确设置为 MainWindowViewModel 这应该可以完成工作

<ContentControl Content="{Binding UserControlViewModel}" />

【讨论】:

  • 是的,这里的主要问题是绑定 ContentControl 的 DataContext 而不是 Content。 DataContext 不控制内容控件将显示的内容。
  • 你是救生员。
  • 你拯救了我的一天
  • 这应该如何工作? ContentControl 应该包含一个视图,而不是一个 ViewModel,对吗?
  • @csstudent1418 没错。您不会直接显示 ViewModel。但是 DataTemplates 将数据(例如 ViewModels)链接到特定的视图,就像在 OP 的示例代码中一样。那么你只需要改变ViewModel,视图就会随之改变。
【解决方案2】:

在执行 mvvm 时,您的视图模型应该实现 INotifyPropertyChanged 而不是从 DependencyObject 继承。

public class MainWindowViewModel : INotifyPropertyChanged
{
   private object _currentWorkspace; //instead of object type you can use a base class or interface
   public object CurrentWorkspace
   {
      get { return this._currentWorkspace; }
      set { this._currentWorkspace = value; OnPropertyChanged("CurrentWorkspace"); }
   }


   public MainWindowViewModel()
   {
      CurrentWorkspace= new EditUserControlViewModel();
   }

   //todo: to switch the workspace, create DelegeCommand/RelayCommand and set the CurrentWorkspace
   //if you don't know about these commands let me know and i post it

   public ICommand SwitchToViewCommand {get{...}}
   public ICommand SwitchToEditCommand {get{...}}
}

xaml:您应该将 Content 属性设置为您的 CurrentWorkspace。

<ContentPresenter Content="{Binding UserControlViewModel}" />
<Button Content="View" Comamnd="{Binding SwitchToViewCommand}"/>
<Button Content="Edit" Comamnd="{Binding SwitchToEditCommand}"/>

!不要忘记将窗口的 DataContext 设置为 MainWindowViewModel 实例。

【讨论】:

    【解决方案3】:

    首先,您应该发布 UserControl 的代码,因为(在上面的代码 sn-p 中)它负责显示一些数据。

    其次,您没有在代码中绑定任何内容。

    第三,您的 ViewModel 实现是错误的。您不需要子类化 DependencyObject,而是实现 INotifyPropertyChanged 接口以建立能够通知您的 View 的 ViewModel。

    第四个我不知道你在做什么

    <ContentControl DataContext="{Binding UserControlViewModel}" />
    

    也许你可以进一步解释一下?

    第五,在实现 MVVM 模式时(你目前不这样做),你应该避免使用像点击事件这样的事件,而是使用命令。

    (我知道这还不是一个真正的答案,但我不想用注释语法写)

    【讨论】:

    • 1) UserControl 代码无关紧要。有 2 个用户控件,并且都只有一个元素,标签(一个内容是“查看”其他的“编辑”)2)见 4)3)你在哪里看到 DependencyObject 子类?这是一个依赖属性。 4)它是带有 DateContext 的 ContentControl,它绑定到 Project.MainWindow ViewModel 中的 UserControlViewModel DependencyProperty
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 2012-10-14
    • 2015-10-22
    • 2016-08-15
    相关资源
    最近更新 更多