我正在开发一个一次性应用程序,但我喜欢利用这些机会来提高我对不熟悉事物的技能。所以我决定使用 MVVM 和 WPF,而不是坚持我的 WinForms 舒适区。我不知道如何让我的 UI 的某些部分相互通信。好吧,这更像是我找不到一种看起来不太可靠的方法。
应用程序测试一种算法的性能,该算法用于从大量收集数据中确定切片的最小值/最大值。 Here's what it looks like.
主窗口的 ViewModel 生成一个包含许多值的集合。我想为切片指定一个范围,然后执行几个版本的最小/最大算法来验证正确性和执行时间。
底部组框中的部分是 UserControl 的两个实例,我将其称为子控件。这对我来说很有意义,因为我知道我需要几个并且不想在主窗口中复制/粘贴集群。这就是问题发生的地方。
主窗口 VM 具有集合和切片范围的属性。我需要子虚拟机才能访问这些属性。事实证明这很困难。理想情况下,我想要这样的东西:
<local:AlgorithmTester RangeStart="{Binding RangeStart}"
RangeEnd="{Binding RangeEnd}"
Values="{Binding Values}" />
子 VM 有自己的 VM。如果我将依赖属性放在控件上,我还必须将这些属性链接到控件的 VM,可能通过代码内绑定(bind)。这对我来说似乎有点不可思议。我想到了以下替代方案,但对我来说似乎都很奇怪:
还有其他解决方案吗?我对现有的那些太挑剔了吗?你会怎么办?
最佳答案
我会让您的 ParentViewModel 包含 ChildViewModel,并使用 DataTemplate 告诉 WPF 它应该使用 local:AlgorithmTester
绘制 ChildViewModel控制
示例 View 模型
public class ParentViewModel
{
// Actual implementation omitted for sake of simplicity
public ChildViewModel TestViewModelA { get; set; }
public ChildViewModel TestViewModelB { get; set; }
}
示例 XAML
<Window>
<Window.Resources>
<!-- Data Template to tell WPF how to draw the ViewModels -->
<DataTemplate DataType="{x:Type local:ChildViewModel}">
<local:AlgorithmTester />
</DataTemplate>
<Window.Resources>
<!-- Put ViewModels in ContentControls and let WPF figure out how to display them -->
<UniformGrid Columns="2">
<ContentControl Content="{Binding TestViewModelA}" />
<ContentControl Content="{Binding TestViewModelA}" />
</UniformGrid>
</Window>
您的算法属性(StartRange、EndRange 等)和方法(Calculate())存储在 ChildViewModel 中,而 AlgoritmTester 是使 ViewModel 用户友好的 View 。例如,它看起来像这样:
<UniformGrid Columns="2" Rows="4">
<TextBlock Text="Minimum:" />
<TextBox Text="{Binding StartRange}" />
<TextBlock Text="Maximum:" />
<TextBox Text="{Binding EndRange}" />
<TextBlock Text="Elapsed:" />
<TextBox Text="{Binding Elapsed}" />
<Button Content="Calculate" Command="{Binding CalculateCommand}" />
</UniformGrid>
编辑
关于对上述问题的评论,您的 ParentViewModel 将负责将范围传递给 ChildViewModels。
例如,如果范围是静态的,您可以在创建时设置它:
TestViewModelA = new ChildViewModel();
TestViewModelA.StartRange = 0;
TestViewModelA.EndRange = 10;
如果它是动态的,我会注册一个 PropertyChanged 事件处理程序来设置范围
void ParentViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "StartRange":
TestViewModelA.StartRange = this.StartRange;
TestViewModelB.StartRange = this.StartRange;
break;
case "EndRange":
TestViewModelA.EndRange = this.EndRange ;
TestViewModelB.EndRange = this.EndRange ;
break;
}
}
关于mvvm - 如何在一个窗口中创建 VM 之间的 MVVM 父/子关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6681954/