WPF DataTemplate,TemplateSelectors,ContentPresenter基于SelectedItem

时间:2017-06-09 08:16:25

标签: c# wpf datatemplate contentpresenter datatemplateselector

我很困惑使用什么以及如何启动实现,但我希望在更改某个网格时显示基于Enum属性。

目前我有20个网格,在属性更改时使用可见性。 这对于两件事来说并不理想。所有20个网格都将从启动中绑定,并且不利于性能。其次是一些"网格"对于枚举属性的某些值是相同的。所以我在一些网格中有重复的代码。

现在我拥有的是一个枚举:

   public enum MyEnumsForDropDown
    {
        Enum1= 1,
        Enum2= 2,
        Enum3= 3,
        Enum4= 4,
        Enum5= 5
    }

我的ViewModel中的My Object,我绑定的是:

Public class MyObject
{
  private Enums.MyEnumsForDropDown _myChosenEnum;
  public Enums.MyEnumsForDropDown MyChosenEnum
  {
    get { return _myChosenEnum; }
    set
    {
      _myChosenEnum = value;
      this.NotifyPropertyChanged( x => x.MyChosenEnum );
    }
  }
}

我的XAML:

<ComboBox ItemsSource="{Binding CollectionOfEnums}" 
DisplayMemberPath="Value" SelectedValuePath="Key" SelectedValue="{Binding 
MyObject.MyChosenEnum}"></ComboBox>

<Grid Grid.Row="1" Grid.Column="3" Visibility="{Binding 
Path=MyObject.MyChoseEnum, Converter={StaticResource 
EnumToVisibleCollapseConverter}, ConverterParameter={x:Static 
myenumsNameSpace:Enums+MyEnumsForDropDown.Enum1}}">
  <TextBlock Content"This Grid displays when Enum1 is chosen"/>
</Grid>

<Grid Grid.Row="1" Grid.Column="3" Visibility="{Binding 
Path=MyObject.MyChoseEnum, Converter={StaticResource 
EnumToVisibleCollapseConverter}, ConverterParameter={x:Static 
myenumsNameSpace:Enums+MyEnumsForDropDown.Enum2}}">
  <TextBlock Content"This Grid displays when Enum2 is chosen"/>
</Grid>

如何更改Grids以某种方式工作,如ContentPresenters或DataTemplates或我需要使用的任何东西,当我的对象中的属性MyChosenEnum发生变化时依赖它?

1 个答案:

答案 0 :(得分:1)

您可以为每个枚举值定义DataTemplate,然后使用ContentControlStyle来显示正确的值:

<ContentControl Content="{Binding MyObject.MyChosenEnum}">
    <ContentControl.Resources>
        <DataTemplate x:Key="Enum1">
            <Grid />
        </DataTemplate>
        <DataTemplate x:Key="Enum2">
            <Grid />
        </DataTemplate>
    </ContentControl.Resources>
    <ContentControl.Style>
        <Style TargetType="ContentControl">
            <Style.Triggers>
                <DataTrigger Binding="{Binding MyObject.MyChosenEnum}"
                             Value="{x:Static myenumsNameSpace:Enums+MyEnumsForDropDown.Enum1}">
                    <Setter Property="ContentTemplate" Value="{StaticResource Enum1}" />
                </DataTrigger>
                <DataTrigger Binding="{Binding MyObject.MyChosenEnum}"
                             Value="{x:Static myenumsNameSpace:Enums+MyEnumsForDropDown.Enum2}">
                    <Setter Property="ContentTemplate" Value="{StaticResource Enum2}" />
                </DataTrigger>
                <!-- and so on for each enum value -->
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

或者您可以使用DataTemplateSelector

public class YourSelector : DataTemplateSelector
{
    public DataTemplate Enum1 { get; set; }
    public DataTemplate Enum2 { get; set; }
    //...

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        MyEnumsForDropDown value = (MyEnumsForDropDown)item;
        switch(value)
        {
            case MyEnumsForDropDown.Enum1:
                return Enum1;
            case MyEnumsForDropDown.Enum2:
                return Enum2;
        }

        return base.SelectTemplate(item, container);
    }
}
<Grid>
    <Grid.Resources>
        <DataTemplate x:Key="Enum1">
            <Grid />
        </DataTemplate>
        <DataTemplate x:Key="Enum2">
            <Grid />
        </DataTemplate>
        <local:YourSelector x:Key="selector" Enum1="{StaticResource Enum1}" Enum2="{StaticResource Enum2}" />
    </Grid.Resources>
    <ContentControl Content="{Binding MyObject.MyChosenEnum}"
                    ContentTemplateSelector="{StaticResource selector}" />
</Grid>