【问题标题】:WPF: Where does MVVM stop and code-behind begins?WPF:MVVM 在哪里停止,代码隐藏从哪里开始?
【发布时间】:2011-07-31 03:54:49
【问题描述】:

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

将人员加载到ListView 是通过实现 MVVM 完成的。奇迹般有效!此外,通过单击Button 将新人添加到集合中也是通过 MVVM 完成的。

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

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

我之所以怀疑应该使用 MVVM 还是代码隐藏,是因为这两个用例都与仅视图 (GUI) 有关,即与模型或应用程序业务逻辑没有交互性。 ListView 项目源绑定到人员集合 ObservableColleciton<Person> 并且当 ListView 填充项目时,与所选人员相关的所有数据都已传递到视图。在第二个用例中,再次,无需转到 ViewModel 以使其触发有关错误用户输入的消息框。在 ViewModel 类的 age 依赖属性中创建一个验证回调怎么样?

感谢所有澄清。

【问题讨论】:

    标签: wpf mvvm code-behind


    【解决方案1】:

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

    <ListView Name="people" .../>
    
    <TextBox Text="{Binding ElementName=people, Path=SelectedItem.FirstName}"/>
    

    或者为了减少编码,将文本框放在自己的面板中,并设置一个DataContext,例如:

    <Grid DataContext="{Binding ElementName=people, Path=SelectedItem}">
        <TextBox Text="{Binding Path=FirstName}"/>
        <TextBox Text="{Binding Path=LastName}"/>
    </Grid>
    

    验证可以与 XAML 挂钩,但执行验证的代码通常在类中实现。 System.Windows.Controls 中有一个方便的抽象类,名为 ValidationRule,可用于快速创建验证器。示例见this blog post

    【讨论】:

      【解决方案2】:

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

      例如,您的第一种情况是,如上面C. Lawrence Wenham 所述,完全可以在 XAML 代码中解决。无需借助代码隐藏来实现此效果。此示例可以扩展为与不一定在列表框等控件中呈现的集合的交互。您可以编写 XAML 代码,通过绑定响应 ViewModel 中集合中当前项的更改。

      您的第二种情况也可以通过 ViewModel 中的 dvalidation 工具以及使用您的 XAML 对这些工具的数据绑定来实现。 IDataErrorInfo 是为此目的而内置的一个很好的机制。 Here is a nice little article 演示了 IDataErrorInfo 的简单使用。

      希望您何时不得不进入代码隐藏的示例很少而且相差甚远。我遇到的一个示例是当控件不支持 ICommand 并且您无法将功能绑定到行为元素时,示例控件是 ListBox。但是有一些技术可以绕过这个限制,as demonstrated in this great SO question。此外,如果您需要在自定义控件中覆盖呈现,则需要在代码隐藏或继承类中执行此操作。

      希望这可以为答案添加更多有用的信息。

      【讨论】:

      • 不错的答案,只是我身边的一个问题。当视图必须有其他模式窗口时,通过单击按钮我会得到一个消息框。我需要在代码隐藏中创建这样的窗口吗?
      • 这是一个棘手的问题。例如,“纯”消息框(是/否/取消)仍将在代码隐藏中完成,但我发现有更好的方法来创建用户体验。现在,一个不仅仅是是/否/取消功能的模态窗口通常应该有一个视图模型和伴随的视图来展示。这是关于这个主题的一个很好的问题/答案。 stackoverflow.com/questions/454868/…
      【解决方案3】:

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

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

      • 另一种(半严肃但通常有效的)方法来决定某些东西是属于模型还是属于 viewModel 是问自己如果将视图(Window、UserControl 或其他)提供给您的平面设计师(即使你没有,假装你有)。如果您认为他可以将他的 c#-incompetent[*] 手放在后面的代码上(并把它弄得一团糟),这通常表明代码是严格与演示相关的并且可以安全地存在于看法。 大多数情况下,您最终会将其移至 ViewModel。

      [*] 只是出于教育目的,许多设计师比我更能胜任 c# :-)

      【讨论】:

        【解决方案4】:

        您可以使用validation rule 进行绑定。它不会显示消息框(尽管它可能是可能的),但您可以定义一个显示错误的ErrorTemplate

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-02-21
          • 1970-01-01
          • 1970-01-01
          • 2018-02-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多