WPF:MVVM在哪里停止并且代码隐藏开始了?

Bor*_*ris 7 wpf code-behind mvvm

我创建了一个窗口,其中包含一个ListView显示人员集合的窗口.还有3个TextBoxes应该显示人的名字和姓氏,以及年龄.最后,有一个Button保存在这些TextBoxes中输入的新人数据.

ListView通过实现MVVM来加载人员.奇迹般有效!此外,通过单击Button也可以通过MVVM 将新人添加到集合中.

但是有两个用例,我不确定使用命令是更明智的,即MVVM,还是简单的代码隐藏.用例是:

  1. 当用户从中选择一个人时ListView,TextBoxes应显示人员详细信息.
  2. 当用户键入字符而不是TextBox显示人的年龄的数字时,应警告他或她输入的数据不正确.

我怀疑是否应该使用MVVM或代码隐藏的原因是因为两个用例都与仅视图(GUI)相关,即与模型或应用程序业务逻辑没有交互性.该ListView项目源绑定到人的集合ObservableColleciton<Person>,并与被选择的人的所有数据已经传递到当视图ListView中填充的物品.在第二个用例中,再次,没有必要转到ViewModel,以便让它触发有关错误用户输入的消息框.如何在ViewModel类的age依赖属性中创建验证回调呢?

感谢您的所有澄清.

Chr*_*ham 6

当ListView选择发生变化时,文本框可以并且绝对应该通过XAML中的绑定填充,例如:

<ListView Name="people" .../>

<TextBox Text="{Binding ElementName=people, Path=SelectedItem.FirstName}"/>
Run Code Online (Sandbox Code Playgroud)

或者为了减少编码,使用DataContext集将文本框放在各自的面板中,例如:

<Grid DataContext="{Binding ElementName=people, Path=SelectedItem}">
    <TextBox Text="{Binding Path=FirstName}"/>
    <TextBox Text="{Binding Path=LastName}"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

验证可以在XAML中连接,但执行验证的代码通常在类中实现.System.Windows.Controls调用ValidationRule中有一个方便的抽象类,可用于快速创建验证器.有关示例,请参阅此博客文章.


Dav*_*ite 6

我开始将代码放入代码隐藏文件的唯一一次是我无法将其放入ViewModel或更深入的对象图中.

例如,正如上面提到的C. Lawrence Wenham所说的那样,你首先应该在XAML代码中完全解决问题.没有必要求助于代码隐藏来实现这种效果.此示例可以扩展为与集合的交互,集合不一定在像列表框这样的控件中呈现.您可以编写XAML代码,通过绑定响应ViewModel中集合中当前项的更改.

您的第二种情况也可以通过ViewModel中的dvalidation工具实现,并通过XAML数据绑定到这些工具.IDataErrorInfo是一个很好的机制,内置于此目的.这是一篇很好的小文章,演示了IDataErrorInfo的简单使用.

你不得不陷入代码隐藏的例子很少和远期.我遇到的一个例子是当一个控件不支持ICommand而你无法将功能绑定到一个行为元素时,一个示例控件就是一个ListBox.但是有一些技术可以解决这个限制,正如这个伟大的SO问题所证明的那样.此外,如果您需要在自定义控件中覆盖渲染,则需要在代码隐藏或继承的类中执行此操作.

希望这会为答案添加更多有用的信息.


Fra*_*ori 2

MVVM 背后的主要动机是关注点分离,即将逻辑与表示分离。您所描述的内容(搜索和验证)对我来说看起来更“逻辑”,所以我会将其放入 ViewModel 中(当然假设它不能通过数据绑定执行)。

  • 请记住,视图很难测试,因此如果您正在实现的逻辑有可能存在重大错误,那么这就是将其放入 viewModel 中的原因。

  • 另一种(半严肃但通常有效)的方法来决定某些东西是否属于模型或视图模型,那就是问自己,如果将视图(窗口、用户控件或其他)提供给图形设计师(即使您没有,假装你有)。如果你同意他可以将他的 c#-incompetent[*] 手放在后面的代码上(并把它搞得一团糟),那么这通常表明代码是严格与演示相关的,并且可以安全地存在于看法。大多数时候您最终会将其移至 ViewModel。

[*] 只是出于教育目的,许多设计师比我更擅长 C# :-)