WPF MVVM绑定datacontext的最佳实践

时间:2015-09-17 10:51:50

标签: wpf mvvm binding viewmodel datacontext

我被告知MVVM的最佳实践是将viewmodel传递给视图,因此它在运行时之前不知道datacontext。 (系统1)

然而,我找到的每个帖子都将viewmodel传递给xaml datacontext,这对于MVVM来说似乎并不理想。 (系统2)

在WPF MVVM中绑定datacontext的最佳方法是什么?这对事件处理程序绑定有何影响?

实施例: 我有一个组合框链接到我的ViewModel中的项目。当我使用绑定系统2时,组合框选择会激活' ComboChanged'事件。使用绑定系统1时,组合框选择会更改,但事件不会触发。加载整个页面后,将在手动更改组合框时触发事件。

主机(系统1):

public override void Initialise()
{
    element = new Plugin(new ViewModel(Credentials));
    element.combobox.SelectedIndex = 0;
}

插件(系统1):

public Plugin(ViewModel viewModel)
{
     InitializeComponent();
     ViewModel = viewModel;
     this.DataContext = ViewModel;
     ViewModel.ComboChanged += new EventHandler<ComboChangedEventArgs>(performComboChanged);
}

ViewModel(系统1):

public ViewModel(Credentials credentials)
{
    //Initialisation code
}

主机(系统2):

public override void Initialise()
{
     element = new Plugin(Credentials)
     element.combobox.SelectedIndex = 0;
}

插件(系统2):

public Plugin(Credentials credentials)
{
    InitializeComponent();
    ViewModel = ((ViewModel)this.DataContext);
    ViewModel.Credentials = credentials;
    ViewModel.ComboChanged += new EventHandler<ComboChangedEventArgs>(performComboChanged);
}

//Plugin.xaml
<UserControl.DataContext>
    <local:ViewModel/>
</UserControl.DataContext>

ViewModel(系统2):

public ViewModel()
{
    //Initialisation code
}

提前致谢

1 个答案:

答案 0 :(得分:1)

关于您的事件处理实施:

简而言之:

  • 你永远不应该在你的代码中将事件绑定到VM,甚至在后面的代码中使用你的VM:演示文稿和业务代码会混合在一起,如果你的视图发生了变化,你可能会破坏你的代码逻辑
  • 您永远不应该将您的视图或其中一个控件用于您的视图模型:VM是商业场所,而不是用于演示

我总是记住这一次,特别是当我不得不完全重新组合一个大的复杂视图(重命名控件,从列表框切换到gridview,重新组织网格等等)时:因为我的MVVM很干净(严格分离来自视图/演示文稿的VM /业务)我能够在不触及业务逻辑的任何行的情况下这样做。如果我将所有控制事件直接绑定到我的视图模型,这将是一场噩梦。

从这里你(至少)有两个选择:

  1. 使用交互库,您可以将控件事件绑定到视图模型命令或方法
  2. 创建自己的行为,在控件事件和视图模型命令或属性之间实现此链接。
  3. 这篇文章总结了互动选项:MVVM events