基于 SelectedItem 的 WPF DataTemplate、TemplateSelectors、ContentPresenter
WPF DataTemplate, TemplateSelectors, ContentPresenter based on SelectedItem
我很困惑使用什么以及如何开始实施,但我想要基于枚举 属性 当更改某个网格时应该显示。
目前我有大约 20 个网格,在 属性 更改时使用可见性。
这对于两件事来说并不理想。所有 20 个网格将从启动时绑定,这对性能不利。其次,某些 "Grids" 对于枚举 属性 的某些值是相同的。所以我在一些网格中有重复的代码。
现在我有一个枚举:
public enum MyEnumsForDropDown
{
Enum1= 1,
Enum2= 2,
Enum3= 3,
Enum4= 4,
Enum5= 5
}
我绑定到的 ViewModel 中的我的对象用于:
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>
如何更改网格以某种方式像 ContentPresenters 或 DataTemplates 或任何我需要使用的东西取决于我的对象中的 属性 MyChosenEnum 何时更改?
您可以为每个枚举值定义一个 DataTemplate
,然后使用 ContentControl
和 Style
来显示正确的值:
<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>
我很困惑使用什么以及如何开始实施,但我想要基于枚举 属性 当更改某个网格时应该显示。
目前我有大约 20 个网格,在 属性 更改时使用可见性。 这对于两件事来说并不理想。所有 20 个网格将从启动时绑定,这对性能不利。其次,某些 "Grids" 对于枚举 属性 的某些值是相同的。所以我在一些网格中有重复的代码。
现在我有一个枚举:
public enum MyEnumsForDropDown
{
Enum1= 1,
Enum2= 2,
Enum3= 3,
Enum4= 4,
Enum5= 5
}
我绑定到的 ViewModel 中的我的对象用于:
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>
如何更改网格以某种方式像 ContentPresenters 或 DataTemplates 或任何我需要使用的东西取决于我的对象中的 属性 MyChosenEnum 何时更改?
您可以为每个枚举值定义一个 DataTemplate
,然后使用 ContentControl
和 Style
来显示正确的值:
<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>