使用相同视图模型支持多个视图的最佳方式是什么?
(是的......我已阅读" MVVM(使用WPF) - 将多个视图绑定到SameViewModel",但如果我正确读取它,答案涉及创建不同的视图模型,这不是我想要的在这里)。
在下面的代码中,当InkStringView由定义的行组成时,StringViewModel支持InkStringView。我现在希望定义一个由列组成的第二个视图,但必须保留StringViewModel的相同的 datacontext。在第二个视图中,控件具有不同的位置和大小,StringViewModel 计算但其功能和用途保持不变。如果在字符串中创建StringViewModel的模块(一个observablecollection)不知道将使用哪个视图而将最终决策留给usercontrol的xaml,那将是理想的。
我的问题是如何设计StringViewModel和/或DataTemplate以通过仅更改DataTemplate来允许基于该视图的不同视图和计算。
(我尝试将StringViewModel继承到不同的viewmodel,每个viewmodel特定于其视图,但它不起作用)。
提前感谢您的任何帮助或建议。或者他们是更好的方式?
示例:
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<v:InkStringView_2 /> <----CHANGING THE VIEW TO COLUMNS. ViewModel needs
</DataTemplate> to perform calculations specific to the view.
用户控件是:
<UserControl.Resources>
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<v:InkStringView />
</DataTemplate>
</UserControl.Resources>
<Grid>
<ItemsControl
ItemsSource="{Binding Strings}" >
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Control.Margin" Value="{Binding Margin}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</UserControl>
答案 0 :(得分:1)
只是一个建议:
你有一个viewmodel MyViewmodel,你想用不同的DataTemplates显示它。那么对我来说,一个简单的方法就是创造&#34; new&#34;带有&#34; no&#34;的课程实施
public class MyT1 : MyViewmodel {}
public class MyT2 : MyViewmodel {}
public class MyT3 : MyViewmodel {}
所以现在所有的MyT1,MyT2,MyT3都有相同的方法和内容,但是你可以创建一个数据模板来预测它们
<DataTemplate DataType="{x:Type vm:MyT1}">
<v:T1View />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:MyT2}">
<v:T2View />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:MyT3}">
<v:T3View />
</DataTemplate>
或者您不使用Viewmodel First方法并执行View First,然后您可以使用Datacontext选择所需的视图
答案 1 :(得分:1)
我遇到了类似的问题,我解决问题的方法是使用ControlTemplate
所以:
在您的视图中:
<Control>
<Control.Resources>
<Style TargetType="Control">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Control">
<!-- Here you put you view it could be a UC if you want -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style
</Control.Resources>
</Control>
然后在您的Style.Resources
中,您可以定义Triggers
或DataTriggers
来更改控件的Template
属性。这样就可以保持ViewModel不变,只需更改获取数据的Views即可。希望这是有道理的,如果有什么事情让我们大喊大叫,我会把更多的信息放进去
HTH
答案 2 :(得分:0)
不是答案,而是一个简单的解决方案。
重新定义字符串,ItemsSource,
ObservableCollection<StringViewModelBase> Strings
然后将StringViewModelBase的子项创建为
public class StringByRowViewModel : StringViewModelBase
然后将资源中的DataTemplate更改为
<DataTemplate DataType="{x:Type vm:StringByRowViewModel}">
<v:InkStringByRowView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:StringByColumnViewModel}" >
<v:InkStringByColumnView />
</DataTemplate>
最后,我认为别无选择,只能更改构建字符串的模块(至少就视图模型而言)。而不是
StringViewModelBase svm = new StringViewModelBase(text,color, w);
使用
StringByColumnViewModel svm = new StringByColumnViewModel(text,color,w);
与
Strings.Add(svm);
显然,ObservableCollection只需要一个共同的父级,并且数据类型仍然保留在XAML中。