如何使用其他视图模型的属性初始化视图模型

时间:2019-09-23 15:01:59

标签: wpf mvvm data-binding

我的问题是用WPF,MVVM方式初始化子窗口的理想方法是什么?

我有一个WPF窗口,我们称其为ParentWindow具有其视图模型类-ParentWindowViewModel。单击ParentWindow UI上的一个按钮后,我将启动一个新的WPF窗口-如下所示的ChildWindow

ChildWindow  r = new ChildWindow ();
 r.ShowDialog();           
 r.WindowStartupLocation = WindowStartupLocation.CenterScreen;

现在,ChildWindow具有自己的viewModel,例如-ChildWindowViewModel。子窗口的xaml中将datacontext设置为

<Window.DataContext>
        <viewModel:ChildWindowViewModel/>
    </Window.DataContext>

在父窗口中单击按钮时,当我启动子窗口时,我需要将某些值传递给子窗口,该值将用于初始化子窗口。没有这些值,子窗口将无法初始化。每次单击按钮以启动子窗口时,传递到子窗口的值将根据父窗口中的其他某些选定项而有所不同。

1 个答案:

答案 0 :(得分:1)

我会做这样的事情(不检查错误):

在ParentWindow.xaml.cs

private void Some_Event_In_Parent_Window()
{
   ParentWindowViewModel pvm = DataContext as ParentWindowViewModel;
   ChildWindow cw = new ChildWindow(pvm.Element1, pvm.Element2);
}

int ChildWindow.xaml.cs

public ChildWindow(bool elem1, string elem2)
{
   InitializeComponents();
   DataContext = new ChildWindowViewModel(elem1, elem2);
} 

如果您正在处理需要在Windows / VM之间转移的最少元素,并且主要是关于发送某种形式的“状态”或“值”,那么在代码中初始化Viewmodel不会有太多问题背后。请记住,后面的代码中的<viewmodel:ChildWindowViewModel/>DataContext = new ChildWindowViewModel()等效。是的,您可以创建意大利面条式代码,或者通过不遵循模式来混淆依赖关系。您还可以过度设计一些不需要做的事情,并且可能会造成混乱。

我发现有一种将您的代码保留为空的想法(我也有同样的想法)。请记住,后面的代码是有原因的,您可以使用它。有时候,如果您有一个一次性的要求就可以在代码中添加一些注释来处理,那么通过实施某种大模式来使代码库过于复杂是不值得的。

除了事件处理程序外,我还将以下代码用于以下主要用例:

  1. 需要对UI进行调整,该调整过于复杂,无法仅在XAML中处理。示例:我需要一些奇怪的字符串连接和某些输入文本字段的逻辑。
  2. 视图之间需要传输一些最小的状态或数据。 (根据您的要求)
  3. 需要执行某种逻辑,这些逻辑特定于UI,并且与基础数据或ViewModel不相关。 (这种情况很少见,而且几乎总是一小会儿)。

对于MVVM,“这是理想的”吗?这取决于您对理想的定义。

  • 可以通过其他设计模式来处理吗?大概...?但是这值得吗。
  • 实现上述模式是否只会增加膨胀或仅解决一个小问题的开销?也许。那是你决定的。
  • 您是否会多次重复执行此实现?如果是这样,您可能需要重新设计一些错误的设计。
  • 实现这种在后台使用Code的解决方案是否可以快速解决您的问题,并且该问题需要适当维护和阅读?如果是这样,那么我不会看到问题。

理想并非总是由规则定义。它也特定于您的需求和要求。

确定用例应该在哪里处理并不总是很容易。 View,ViewModel,也许是Service或Singleton状态类。 如果您的用例是一个窗口,那么后面的代码很好(我认为)。如果要在20个窗口中执行此操作,则可能希望服务以某种方式维护状态。想一想-如果您的代码是SOLID and DRY