将WPF设计数据与MVVM模式一起使用

Jus*_*tin 10 wpf xaml prism mvvm design-data

我在WPF应用程序中使用MVVM模式以允许全面的单元测试.MVVM模式本身是伟大的工作,但我挣扎中,这意味着我可以使用设计时数据支持WPF的方式相适应的模式.

当我使用Prism时,ViewModel实例通常被注入到视图的构造函数中,就像这样

public MyView(MyViewModel viewModel)
{
    DataContext = viewModel;
}
Run Code Online (Sandbox Code Playgroud)

然后将ViewModel的依赖项注入构造函数中,就像这样

public class MyViewModel
{
    public MyViewModel(IFoo foo, IBar bar)
    {
        // ...
    }

    // Gets and sets the model represented in the view
    public MyModel { get; set; }

    // Read-only properties that the view data binds to
    public ICollectionView Rows { get; }
    public string Title { get; }

    // Read-write properties are databound to the UI and are used to control logic
    public string Filter { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

除了涉及到设计数据之外,这通常工作得非常好 - 我想避免将特定于设计数据的类编译到我发布的程序集中,因此我选择使用该{d:DesignData}方法而不是{d:DesignInstance}方法,但为了使其正常工作, ViewModel现在需要一个无参数构造函数.此外,我还经常需要更改其他属性以具有setter或可修改集合,以便能够在XAML中设置这些属性.

public class MyViewModel
{
    public MyViewModel()
    {
    }

    public MyViewModel(IFoo foo, IBar bar)
    {
        // ...
    }

    // Gets and sets the model represented in the view
    public MyModel { get; set; }

    // My read-only properties are no longer read-only
    public ObservableCollection<Something> Rows { get; }
    public string Title { get; set; }

    public string Filter { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这令我担心:

  • 我有一个无参数构造函数,从不打算调用,也不进行单元测试
  • 有些属性的setter只有ViewModel本身应该调用
  • 我的ViewModel现在是一个应该由视图修改的属性的混合混合,以及那些不应该修改的属性 - 这使得一目了然哪个代码负责维护任何给定属性变得棘手
  • 在设计时设置某些属性(例如,查看Filter文本样式)实际上最终可以调用ViewModel逻辑!(所以我的ViewModel也需要对设计时缺少的强制依赖项感到厌倦)

有没有更好的方法在WPF MVVM应用程序中以不会以这种方式损害我的ViewModel的方式获取设计时数据?

或者,我应该以不同方式构建我的ViewModel,以便它具有更简单的属性,并将逻辑分离到其他位置.

DRa*_*app -1

我也曾使用 WPF 和 MVVM 实现进行 NUnit 测试。但是,我的版本与你的相反。您首先创建视图,然后创建模型来控制它。

在我的版本中,我首先创建 MVVM 模型,然后可以对它进行单元测试,直到奶牛回家为止,而不用担心任何视觉设计......如果模型被破坏,视觉实现也会被破坏。

在我的 MVVM 模型中,我有一个“GetTheViewWindow”方法。因此,当我从 MVVM 基线派生时,每个视图模型都有自己负责的视图。因此,通过虚拟方法,每个实例在应用于生产时都会创建自己的新视图窗口。

public class MyMVVMBase
{
   private MyViewBaseline currentView;

   public MyMVVMBase()
   { // no parameters required }

   public virtual void GetTheViewWindow()
   { throw new exception( "You need to define the window to get"; ) }
}

public class MyXYZInstanceModel : MyMVVMBase
{
   public override void GetTheViewWindow()
   {
      currentView = new YourActualViewWindow();
   }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以作为您遇到的问题的替代方案有所帮助。

  • 1.这不是MVVM!您的视图模型永远不应该了解视图。2.我在任何地方都看不到这如何解决OP使用设计数据的问题。 (3认同)
  • 对我来说有点奇怪的是你的虚拟机依赖于你的视图。 (2认同)