【问题标题】:WPF MVVM Problems with View视图的 WPF MVVM 问题
【发布时间】:2011-09-18 15:11:02
【问题描述】:

我想在我的项目中使用带有 MVVM 模式的 WPF,但我对一些关于 MVVM 模式的观点感到困惑。请帮助我澄清这些观点。

  1. 我正在为 ViewModel 使用 DataTemplate,但我希望特定控件以键盘为中心。
  2. 如何在执行 ICommand 后关注特定控件。
  3. 如何将焦点转移到未验证的控件。
  4. 有什么方法可以根据 ViewModel 属性值分离 DataTemplate。
  5. 如何在 ICommand 之前验证所有控件
  6. 还有其他更好的方法可以通过 MessageBox 向 ViewModel 询问任何确认

问候, 密探

【问题讨论】:

  • 1 - 取决于您的代码和架构 2 - 相同 3 - 以编程方式在代码后面 4 - 我不明白这个问题? 5 - 在你的模型/视图模型中实现IDataErrorInfo 6 - 我个人使用MessageBox,我不知道为什么我应该改变它:)

标签: wpf mvvm mvvm-light


【解决方案1】:

我强烈建议您查看caliburn(或caliburn.micro),它公开了不同的 UImanager 接口,以便您的视图模型可以在不丢失单元可测试性的情况下执行此类操作。

【讨论】:

    【解决方案2】:

    要将焦点设置在控制上,请使用代码隐藏。 MVVM 并没有说不要使用代码隐藏。

    在后面的代码上写一个方法来设置焦点并从视图模型中调用这个方法。

    例子

    public interface IView
    {
      void setFoucs();
    }
    
    //Code Behind
    public class MyWindow : Window, IView
    {
      public void SetFoucs()
      {
        MyControl.Focus();
      }
    }
    
    public class ViewModel
    {
      public IView _view { get; set; }
      public ViewModel(IView view)
      {
       _view = view;
      }
    
      public void SomeMethod()
      {
       _view.SetFocus();
      }
    
    }
    

    对于第 4 个问题 - 我认为您希望根据您的某些逻辑选择特定的数据模板。要实现这一点,请使用 DataTemplateSelector 类。

    http://www.switchonthecode.com/tutorials/wpf-tutorial-how-to-use-a-datatemplateselector

    【讨论】:

    • 这将 View 和 ViewModel 结合得太紧,会导致一些混合性问题,因此,我建议改用消息传递。
    【解决方案3】:

    问题一:

    不清楚你的意思/想要什么。通常,TabIndex 控制应用程序中的焦点流,但使用 silverlight 它不像在 windows 窗体中那样容易配置。 Silverlight 在自动设置制表符顺序方面也做得很好。

    但是,您应该注意,默认情况下,从 Control 继承的所有控件都接收焦点。这包括一些可用作其他控件(例如 ContentControl)的容器的控件。此行为可能会导致一些不良影响。使用 IsTabStop 属性从 Tab 键顺序中删除这些控件。

    问题 2:

    嗯,这取决于您希望应用程序如何解耦(解耦越多越好)。 @pcajer 的方法是这样做的一种方式,但是它将视图与视图模型耦合起来,尽管这是通过接口抽象的,但恕我直言不是一个好主意,原因如下:

    1. 通常,视图模型是从定位器中提取的,以实现可混合性。现在,如果我必须使用后面的代码将 View 传递给 ViewModel,这可能会破坏它。如果它可以通过构造函数参数注入到 ViewModel 中会更好,这样会破坏定位器。
    2. 代码变得不太可测试,因为它现在依赖于视图。为了使其可测试,您需要将 IView 的实现注入 ViewModel,这会再次破坏定位器。

    因此,我建议您在命令完成后使用消息传递向您的视图发送消息。然后您可以在消息处理程序中设置焦点。但是请注意,您可能必须使用 Dispatcher,因为消息处理程序可以在单独的线程中运行。

    问题 3:

    您可以捕获控件上的 BindingValidationError,然后设置焦点。再次注意可能的线程问题。

    问题 4:

    不确定,但是如果您的意思是要根据属性是否具有特定值来使用不同的 DataTemplates,那么 TemplateSelector 可能会对您有所帮助。见http://www.switchonthecode.com/tutorials/wpf-tutorial-how-to-use-a-datatemplateselector

    问题 5:

    在触发属性更改事件时验证控件,通常是在失去焦点事件上。您的 Model/ViewModel 可以实现 IDataError 来进行验证,并且您可以从与您的命令关联的 CanExecute 方法访问此值。但是,您应该尽量保持 CanExecute 方法中的代码尽可能快,因为此方法被频繁调用。

    问题 6:

    您可以实现自己的提供自定义布局的窗口。但是,使用消息框要简单得多。同样,您应该考虑使用消息传递或对话服务(例如http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/)来解耦您的视图和视图模型。事实上,在 MVVMLight 中甚至还有一个 DialogMessage。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-15
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      • 2013-07-07
      • 1970-01-01
      • 2013-11-08
      相关资源
      最近更新 更多