根据选择切换ListBoxItem的ContentPresenter
我试图在选择 ListBoxItem 时切换其 ContentPresenter,同时使用多个 DataTemplate 来表示不同类型的数据。
下面是定义内部 ListBox 的 UserControl:
<UserControl x:Class="Homage.View.FilePanelView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vw="clr-namespace:Homage.View"
xmlns:vm="clr-namespace:Homage.ViewModel"
xmlns:ctrl="clr-namespace:Homage.Controls"
mc:Ignorable="d">
<UserControl.Resources>
<DataTemplate DataType="{x:Type vm:SlugViewModel}">
<vw:SlugView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:HeaderSlugViewModel}">
<vw:HeaderSlugView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:ContentSlugViewModel}">
<vw:ContentSlugView />
</DataTemplate>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border Name="SlugContainer" Background="Transparent" BorderBrush="Black" BorderThickness="1" CornerRadius="2" Margin="0,5,0,0" Padding="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Content="{Binding DisplayName}" />
<ContentPresenter Grid.Row="1" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="SlugContainer" Property="BorderThickness" Value="5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<ListBox ItemsSource="{Binding Slugs}" Padding="5" />
</Grid>
</UserControl>
根据要显示的数据类型(例如,“Header Slug”),将特定的 DataTemplate 应用到 ListBoxItem。这工作得很好,但我想根据显示的数据类型将所选 ListBoxItem 的 DataTemplate 调整为不同的 DataTemplate。
目标是,由于每种数据类型都不同,因此每种数据类型在未选择时将具有独特的外观,并且在选择时将收到一组唯一的选项。
如果我能实现上述工作,那就太好了!但是,我也想让事情变得复杂......
虽然每种数据类型都有独特的控件,但它们也有通用的控件。因此,我理想地希望将所有公共控件定义一次,以便它们出现在列表框中的同一位置。
<DataTemplate x:Key="CommonSelectedTemplate">
<!-- common controls -->
...
<DataTemplate x:Key="UniqueSelectedTemplate">
<!-- all the unique controls -->
<ContentPresenter />
</DataTemplate>
<!-- more common controls -->
...
</DataTemplate>
如果我必须多次定义所有常见的东西(现在)我会活下去。 =)
感谢您的帮助!
I am trying to switch out the ContentPresenter of a ListBoxItem when it is selected, while using multiple DataTemplates to represent different types of data.
Here is the UserControl that defines the ListBox inside:
<UserControl x:Class="Homage.View.FilePanelView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vw="clr-namespace:Homage.View"
xmlns:vm="clr-namespace:Homage.ViewModel"
xmlns:ctrl="clr-namespace:Homage.Controls"
mc:Ignorable="d">
<UserControl.Resources>
<DataTemplate DataType="{x:Type vm:SlugViewModel}">
<vw:SlugView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:HeaderSlugViewModel}">
<vw:HeaderSlugView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:ContentSlugViewModel}">
<vw:ContentSlugView />
</DataTemplate>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border Name="SlugContainer" Background="Transparent" BorderBrush="Black" BorderThickness="1" CornerRadius="2" Margin="0,5,0,0" Padding="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Content="{Binding DisplayName}" />
<ContentPresenter Grid.Row="1" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="SlugContainer" Property="BorderThickness" Value="5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<ListBox ItemsSource="{Binding Slugs}" Padding="5" />
</Grid>
</UserControl>
Based on the type of data to be shown (e.g., a "Header Slug") a certain DataTemplate is applied to the ListBoxItem. This is working great, but I am wanting to adjust the DataTemplate of the selected ListBoxItem to a different DataTemplate -- again, based on the data type being shown.
The goal is that, because each data type is different, each would have a unique look when not selected and would receive a unique set of options when selected.
If I can get the above to work, that would be great! But, I also want to complicate things...
While each data type has unique controls they also have common controls. So I would ideally like to define all the common controls once so that they appear in the same place in the ListBox.
<DataTemplate x:Key="CommonSelectedTemplate">
<!-- common controls -->
...
<DataTemplate x:Key="UniqueSelectedTemplate">
<!-- all the unique controls -->
<ContentPresenter />
</DataTemplate>
<!-- more common controls -->
...
</DataTemplate>
If I have to define all the common stuff multiple times (for now) I'll live. =)
Thanks for any help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
假设我们只有两种数据类型:
Item1ViewModel
和Item2ViewModel
。因此我们需要4个数据模板:2个用于公共状态,2个用于选定状态。为了根据不同类型在两个模板之间切换内容,我使用 DataTemplateSelector 类:
我们需要此选择器的两个实例:一个用于公共状态,一个用于选定状态。
之后,您应该添加此代码来切换两个选择器:
就这样,将此
ItemTemplate
应用于您的ListBox
,而不更改ControlTemplate
:Let's suppose that we have only two data types:
Item1ViewModel
andItem2ViewModel
. Therefore we need 4 data templates: 2 for the common state, 2 for the selected state.For switching the content between two templates based on different types I use the
DataTemplateSelector
class:We need two instances of this selector: one for the common state and one for the selected state.
And after that you should add this code which switches two selectors:
That's all, apply this
ItemTemplate
to yourListBox
without changing theControlTemplate
: