我正在研究一次性应用程序,但我喜欢用这些作为一个机会,通过不熟悉的东西来提高我的技能。所以我决定使用MVVM和WPF而不是坚持我的WinForms舒适区。我无法弄清楚如何让我的UI与他人交谈。嗯,这更像是我找不到一种方法来做这件事并不会让人感到不舒服。
应用程序的测试性能,用于确定大型集合数据中切片的最小值/最大值。 Here's what it looks like.
主窗口的ViewModel生成一个包含许多值的集合。我想为切片指定一个范围,然后执行几个版本的最小/最大算法来验证正确性和执行时间。
底部的组框中的部分是UserControl的两个实例,我将调用子控件。这对我来说很有意义,因为我知道我需要几个并且不想在主窗口中复制/粘贴集群。这就是麻烦发生的地方。
主窗口VM具有集合和切片范围的属性。我需要子VM才能访问这些属性。这证明是困难的。理想情况下,我想要这样的东西:
<local:AlgorithmTester RangeStart="{Binding RangeStart}"
RangeEnd="{Binding RangeEnd}"
Values="{Binding Values}" />
子VM具有自己的VM。如果我在控件上放置依赖属性,我必须将这些属性链接到控件的VM,可能是通过代码内绑定。这对我来说似乎有点不可思议。我想到了以下几种选择,但对我来说似乎都很奇怪:
还有其他解决方案吗?我对那些存在的东西过于挑剔吗?你会做什么?
答案 0 :(得分:4)
我希望你的ParentViewModel包含ChildViewModel,并使用DataTemplate告诉WPF它应该使用local:AlgorithmTester
控件
示例ViewModel
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用户友好的视图。例如,它看起来像这样:
<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;
}
}
答案 1 :(得分:1)
我个人要么将它们作为具有依赖属性的UserControls,并将它们绑定在主视图模型中,如图所示。 Alternativley,以及我实际要做的是使用像Caliburn.Micro这样的MVVM框架,这使得视图合成非常容易。
在Caliburn.Micro的情况下,您的主视图模型上将有2个公共属性,每个属性类型为AlgorithmTesterViewModel
,并且在主视图2 ContentControl
上的名称与您的2个公共相同属性。
Caliburn.Micro将通过命名约定自动定位AlgorithmTesterView
,将视图注入2 ContentControl
(通过幕后的DataTemplates),并将每个控件绑定到属性在AlgorithmTesterViewModel
上。
然后,您将在主视图模型中实例化两个AlgorithmTesterViewModel
,传入适当的数据,并将它们分配给2个公共属性。
顺便说一下,你看起来很像David Mitchell。这既不是侮辱,也不是补充。只是观察事实。