Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf MVVM中的数据模板是否过时?_Wpf_Mvvm_Mvvm Light - Fatal编程技术网

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>
免责声明,单选按钮中的绑定使用来自的转换器。

绝对不是(它们是否过时)

  • 是的,这很有道理,但是你的绑定,没有那么多。这些问题可以以多种不同的方式处理。例如,帐户可以有一个父属性,它公开了它所包含的ViewModel(我没有说这是最好的方法)
  • 这是ViewModel设计的一个问题,您必须绑定ViewModel而不是帐户。可以更改设计,这样您就不需要这样做;您提供的快照很难说
  • 我认为这在这一点上对你没有帮助。我想看看是否有办法将与ViewModel相关的UI排除在DataTemplate之外
  • 这里有一个很好的解决方案:创建一个基于
    帐户
    属性选择模板的模板。这样,您可以将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 { ... } 
        ...
    }