c# - 在应用 Mode-View-ViewModel 设计模式时包括部分 View

标签 c# wpf design-patterns mvvm

假设我有一个只处理 Messages 的应用程序和 Users我希望我的窗口有一个共同的 Menu和当前View所在的区域显示。

我只能处理 Messages 或 Users,所以我不能同时处理这两个 View。因此我有以下控件

  • MessageView.xaml
  • 用户 View .xaml

只是为了让它更容易一点,Message ModelUser Model看起来像这样:

  • 姓名
  • 描述

现在,我有以下三个 ViewModel:

  • 主窗口 View 模型
  • 用户 View 模型
  • 消息 View 模型

UsersViewModelMessagesViewModel两者都只是获取一个 ObserverableCollection<T>关于 Model绑定(bind)在对应的View像这样:

<DataGrid ItemSource="{Binding ModelCollection}" />

MainWindowViewModel连接两个不同的 Commands已实现 ICommand看起来像下面这样:

public class ShowMessagesCommand : ICommand
{
    private ViewModelBase ViewModel { get; set; } 
    public ShowMessagesCommand (ViewModelBase viewModel)
    {
        ViewModel = viewModel;
    }
    public void Execute(object parameter)
    {
        var viewModel = new ProductsViewModel();
        ViewModel.PartialViewModel = new MessageView { DataContext = viewModel };
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;
}

还有另一个类似的将显示给用户。现在介绍ViewModelBase它只包含以下内容:

    public UIElement PartialViewModel
    {
        get { return (UIElement)GetValue(PartialViewModelProperty); }
        set { SetValue(PartialViewModelProperty, value); }
    }

    public static readonly DependencyProperty PartialViewModelProperty =
        DependencyProperty.Register("PartialViewModel", typeof(UIElement), typeof(ViewModelBase), new UIPropertyMetadata(null));

此依赖属性用于 MainWindow.xaml显示 User Control像这样动态地:

<UserControl Content="{Binding PartialViewModel}" />

这个 Window 上还有两个按钮触发命令:

  • 显示消息命令
  • 显示用户命令

当这些被触发时,UserControl 会改变,因为 PartialViewModel是一个依赖属性。

我想知道这是否是不好的做法?我不应该像这样注入(inject)用户控件吗?是否有另一个与设计模式更好对应的“更好”的选择?还是这是包含部分 View 的好方法?

最佳答案

为什么不在主窗口中使用带有数据模板的 ContentPresenter/ContentControl?

代替 UserControl Content="{Binding PartialViewModel}"/>,您可以使用:

 <ContentPresenter Content="{Binding Path=PartialViewModel}" />

您所要做的就是:将您的 PartialViewmodel 设置为您的 subview 模型并创建一个数据模板,这样 wpf 就会知道如何呈现您的 subview 模型

<DataTemplate DataType={x:Type UserViewModel}>
    <UserView/>
</DataTemplate> 

<DataTemplate DataType={x:Type MessageViewModel}>
    <MessageView/>
</DataTemplate> 

当您在 MainView 模型中设置 PartialView 模型时,正确的 View 将呈现在您的 ContenControl 中。

编辑 1 至少你必须在你的 ViewModel 中实现 INotifyPropertyChanged 并在设置 PartViewModel 属性时触发它。

编辑 2 如果您在 View 模型中使用命令,请查看一些 mvvm 框架实现,例如 DelegateCommand 或 RelayCommand。有了这个,处理 ICommand 变得容易多了。在您的 mainviewmodel 中,您可以创建这样简单的命令

private DelegateCommand _showMessageCommand;
public ICommand ShowMessageCommand
{
    get
    {
         return this._showMessageCommand ?? (this._showMessageCommand = new DelegateCommand(this.ShowMessageExecute, this.CanShowMessageExecute));
        }
    }

关于c# - 在应用 Mode-View-ViewModel 设计模式时包括部分 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5229645/

相关文章:

c# - MVVM 中异步命令的自动化测试

java - 处理父类(super class)型的所有子类型

c# - 工厂模式应该放在 DDD 中的什么位置?

c# - 我怎样才能让父类知道注入(inject)类的变化

c# - 如何构建 WCF Web 服务解决方案,以便轻松以不同方式进行开发和托管?

c# - 如何获取 Zendesk 中的所有用户

Java - 反转字符串中的单词

c# - 使用 C# 解密 Coldfusion 中的加密字符串

c# - WPF 从 TreeView 中移除 ScrollViewer

WPF 数据网格 : SelectionChanged event isn't raised when SelectionUnit ="Cell"