Wpf MVVM中的数据模板是否过时?
我创建了以下模型(简化代码以说明这种情况): 接下来,我创建了一个视图模型:Wpf MVVM中的数据模板是否过时?,wpf,mvvm,mvvm-light,Wpf,Mvvm,Mvvm Light,我创建了以下模型(简化代码以说明这种情况): 接下来,我创建了一个视图模型: public class ViewModel { public Account Model { ... } public string Name { ... } public string FirstName { ... } public string LastName { ... } public string Owner { ... } ... } 最后,我想
public class ViewModel
{
public Account Model { ... }
public string Name { ... }
public string FirstName { ... }
public string LastName { ... }
public string Owner { ... }
...
}
最后,我想谈谈以下观点:
<UserControl>
<UserControl.Resources>
<!-- Person data template -->
<DataTemplate x:Key="personTemplate" DataType="{x:Type model:Person}">
<Grid DataContext="{Binding ElementName=rootLayout, Path=DataContext}">
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=FirstName}" />
<TextBlock Text="{Binding Path=LastName}" />
</Grid>
</DataTemplate>
<!-- Company data template -->
<DataTemplate x:Key="companyTemplate" DataType="{x:Type model:Company}">
<Grid DataContext="{Binding ElementName=rootLayout, Path=DataContext}">
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=Owner}" />
</Grid>
</DataTemplate>
<!-- Data template selector for different account types -->
<local:AccountTemplateSelector x:Key="templateSelector"
PersonTemplate="{StaticResource personTemplate}"
CompanyTemplate="{StaticResource companyTemplate}" />
</UserControl.Resources>
<StackPanel Name="rootLayout" DataContext="{Binding Path=viewModel}">
<ContentControl Content="{Binding Path=Model}"
ContentTemplateSelector="{StaticResource templateSelector}"/>
<Button Content="Save" />
<Button Content="Close" />
</StackPanel>
</UserControl>
在视图中,人员的数据模板当然也发生了变化:
<!-- Person data template -->
<DataTemplate x:Key="personTemplate" DataType="{x:Type model:Person}">
<Grid DataContext="{Binding ElementName=rootLayout, Path=DataContext}">
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=FirstName}" />
<TextBlock Text="{Binding Path=LastName}" />
<RadioButton Name="Female" />
<RadioButton Name="Male" />
<RadioButton Name="NotSpecified" />
</Grid>
</DataTemplate>
如果
ContentControl
的Content
设置为ViewModel
的Model
属性,我将如何解决性别/单选按钮的情况;因为,现在它们在一个控件/一个属性的方式上不匹配?我将其更改为:
<UserControl>
<UserControl.Resources>
<!-- Person data template -->
<DataTemplate DataType="{x:Type model:Person}">
<Grid>
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=FirstName}" />
<TextBlock Text="{Binding Path=LastName}" />
<RadioButton Name="Female" IsChecked="{Binding Gender , Converter={StaticResource enumBooleanConverter}, ConverterParameter=Female}" />
<RadioButton Name="Male" IsChecked="{Binding Gender , Converter={StaticResource enumBooleanConverter}, ConverterParameter=Male}" />
<RadioButton Name="NotSpecified" IsChecked="{Binding Gender , Converter={StaticResource enumBooleanConverter}, ConverterParameter=NotSpecified }" />
</Grid>
</DataTemplate>
<!-- Company data template -->
<DataTemplate DataType="{x:Type model:Company}">
<Grid>
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=Owner}" />
</Grid>
</DataTemplate>
</UserControl.Resources>
<StackPanel DataContext="{Binding viewModel}">
<ContentControl Content="{Binding Model}" />
<Button Content="Save" />
<Button Content="Save" />
<Button Content="Close" />
</StackPanel>
</UserControl>
免责声明,单选按钮中的绑定使用来自的转换器。绝对不是(它们是否过时)
帐户
属性选择模板的模板。这样,您可以将ItemsSource直接绑定到DataContext,并且它将在DataTemplate中可用@马库斯:谢谢你的回答。如果我在
Person
类中有一个Birthday
属性,并且我希望它像这样显示:“Born on”-在视图模型中为它创建一个属性并在那里格式化/转换它(这会使“clean”数据模板出现问题),或者为它创建一个转换器更好吗?谢谢哦,让我们假设在这里使用StringFormat
是不可能的,因为这里要详细解释的原因太多了。@Boris您可以在viewmodel上定义如下属性:DateTime birth
。然后我会使用StringFormat或转换器来显示它。@Markus:再次感谢。看来生日的例子并不能很好地说明我的担忧。这就是为什么我在我的问题中添加了一些更新来解释我所面临的问题。我非常喜欢您为ContentControl
的Content
属性提供Model
的想法!唯一的问题是,我不知道如何处理性别财产。如果你能帮我做这件事,那就太好了@Boris为了适应您的更新,我建议使用组合框选择女性/男性内容,如@Boris,如果您真的想使用单选按钮,请查看答案以感谢您的回答。我对我的问题做了一些更新。那么现在,如果我绑定帐户
,我将如何处理性别
属性,因为我不能只将性别绑定到3个单选按钮。或者如果我愿意,你能解释一下怎么做吗?谢谢大家!@沃特斯:说得好!实际上,下面提供的解决方案也暗中打乱了这个问题。感谢您加入。1)我将删除模型属性以外的4个其他属性。3) 一个视图模型可以有多个数据模板。4) 他们以浪漫的方式继承它。更新问题:使用列表框并将ItemContainerStyle属性更改为与单选按钮类似。投票支持与带有单选按钮的面板类似的列表框。@Boris我偶尔按下Enter按钮。无论如何,我想说的几乎和Markus说的一样:删除不必要的属性并绑定到rootLayout。@Boris如果你喜欢这个想法,我可以共享我在应用程序中使用的这个模板的代码:如下设置:ItemContainerStyle=“{StaticResource RadioButtonItemContainerStyle}”
。但它来自Silverlight,所以我不知道它在WPF中如何工作。
<!-- Person data template -->
<DataTemplate x:Key="personTemplate" DataType="{x:Type model:Person}">
<Grid DataContext="{Binding ElementName=rootLayout, Path=DataContext}">
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=FirstName}" />
<TextBlock Text="{Binding Path=LastName}" />
<RadioButton Name="Female" />
<RadioButton Name="Male" />
<RadioButton Name="NotSpecified" />
</Grid>
</DataTemplate>
<UserControl>
<UserControl.Resources>
<!-- Person data template -->
<DataTemplate DataType="{x:Type model:Person}">
<Grid>
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=FirstName}" />
<TextBlock Text="{Binding Path=LastName}" />
<RadioButton Name="Female" IsChecked="{Binding Gender , Converter={StaticResource enumBooleanConverter}, ConverterParameter=Female}" />
<RadioButton Name="Male" IsChecked="{Binding Gender , Converter={StaticResource enumBooleanConverter}, ConverterParameter=Male}" />
<RadioButton Name="NotSpecified" IsChecked="{Binding Gender , Converter={StaticResource enumBooleanConverter}, ConverterParameter=NotSpecified }" />
</Grid>
</DataTemplate>
<!-- Company data template -->
<DataTemplate DataType="{x:Type model:Company}">
<Grid>
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=Owner}" />
</Grid>
</DataTemplate>
</UserControl.Resources>
<StackPanel DataContext="{Binding viewModel}">
<ContentControl Content="{Binding Model}" />
<Button Content="Save" />
<Button Content="Save" />
<Button Content="Close" />
</StackPanel>
</UserControl>
public class ViewModel
{
public Account Model { ... }
...
}