假设我有一个只处理 Messages
的应用程序和 Users
我希望我的窗口有一个共同的 Menu
和当前View
所在的区域显示。
我只能处理 Messages 或 Users,所以我不能同时处理这两个 View。因此我有以下控件
- MessageView.xaml
- 用户 View .xaml
只是为了让它更容易一点,Message Model
和 User Model
看起来像这样:
- 姓名
- 描述
现在,我有以下三个 ViewModel:
- 主窗口 View 模型
- 用户 View 模型
- 消息 View 模型
UsersViewModel
和 MessagesViewModel
两者都只是获取一个 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/