WPF Listbox 控件模板不显示 Listboxitem 控件模板和 ItemTemplate 数据模板
Posted
技术标签:
【中文标题】WPF Listbox 控件模板不显示 Listboxitem 控件模板和 ItemTemplate 数据模板【英文标题】:WPF Listbox control template not showing Listboxitem control template and ItemTemplate data template 【发布时间】:2020-05-12 11:46:08 【问题描述】:当我在我的 ListBox 控件模板中使用 ItemsControl 时,我的 ListBoxItem 控件模板没有应用。
我有一个自定义 ListBox 控件模板以及一个包裹在样式中的 ListBoxItem 控件模板。在我的主窗口中,我有一个带有数据模板的 ListBox 声明。
控制模板:
<Style TargetType="ListBoxItem" BasedOn="StaticResource Base_Control_Style">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="x:Type ListBoxItem">
<Border x:Name="border" BorderThickness="0"
BorderBrush="Transparent" Background="Transparent">
<ContentPresenter Content="TemplateBinding Content" Margin="2"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="border" Property="Background"
Value="StaticResource Base_PrimaryLight"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True" >
<Setter TargetName="border" Property="Background"
Value="StaticResource Base_Secondary"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsSelected" Value="True"/>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter TargetName="border" Property="Background"
Value="StaticResource Base_SecondaryDark"/>
</MultiTrigger.Setters>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ListBox" BasedOn="StaticResource Base_Control_Style">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="StaticResource Base_PrimaryDark"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Border x:Name="Border" BorderThickness="TemplateBinding BorderThickness"
BorderBrush="TemplateBinding BorderBrush" Background="TemplateBinding Background">
<ScrollViewer Margin="2">
<!--<StackPanel IsItemsHost="true"/>-->
<!--<ItemsPresenter/>-->
<ItemsControl ItemsSource="TemplateBinding ItemsSource"
ItemTemplate="TemplateBinding ItemTemplate"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
列表框声明:
<ListBox x:Name="recipients_listbox" Margin="10" ItemsSource="Binding Path=Recipients"
SelectedValuePath="Email"
SnapsToDevicePixels="True"
HorizontalContentAlignment="Stretch" ScrollViewer.CanContentScroll="False">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="2,4" HorizontalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Black"/>
</Style>
</Grid.Resources>
<Image Source="Binding ImagePath"
RenderOptions.BitmapScalingMode="HighQuality"
SnapsToDevicePixels="True"
Grid.Column="0" Grid.Row="0" Grid.RowSpan="3"
Stretch="UniformToFill" Margin="0,0,10,0"/>
<TextBlock Text="Name:" FontWeight="Bold"
Grid.Column="1" Grid.Row="0" VerticalAlignment="Center"/>
<TextBlock Text="Email:" FontWeight="Bold"
Grid.Column="1" Grid.Row="1" VerticalAlignment="Center"/>
<TextBlock Text="Department:" FontWeight="Bold"
Grid.Column="1" Grid.Row="2" VerticalAlignment="Center"/>
<TextBlock VerticalAlignment="Center" Grid.Column="3" Grid.Row="0">
<Run Text="Binding FirstName"/>
<Run Text="Binding LastName"/>
</TextBlock>
<TextBlock Text="Binding Email"
VerticalAlignment="Center" Grid.Column="3" Grid.Row="1"/>
<TextBlock Text="Binding Department"
VerticalAlignment="Center" Grid.Column="3" Grid.Row="2"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
问题是当我在我的 ListBox 控件模板中使用 ItemsControl 时,我的 ListBoxItem 控件模板没有应用(更改背景颜色的触发器不会激活),而我的数据模板是。
带有 ItemsControl 的列表框
我尝试使用带有 isItemsHost=True 的 StackPanel 以及 ItemsPresenter。这两个选项都应用了我的 ListBoxItem 控件模板,但没有应用我的数据模板。
带有 StackPanel 或 ItemsPresenter 的列表框
有什么方法可以同时应用我的 ListBoxItem 控件模板和数据模板?
【问题讨论】:
在 ListBox 的 ControlTemplate 中有一个 ItemsControl 是没有意义的。应该有一个 StackPanel 或一个 ItemsPresenter。见这里:docs.microsoft.com/en-us/dotnet/framework/wpf/controls/… “没有应用我的数据模板”到底是什么意思?项目模板? 当我有一个 ItemsPresenter 或 StackPanel 而不是 ItemsControl 时,我在第二个代码 sn-p 中定义的 ItemTemplate 不适用。 【参考方案1】:ListBoxItem 样式中 ControlTemplate 中的 ContentPresenter 不使用 ContentTemplate
属性,该属性包含 ListBox 的 ItemTemplate
属性的 DataTemplate。
添加适当的 TemplateBinding:
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border ...>
<ContentPresenter Content="TemplateBinding Content"
ContentTemplate="TemplateBinding ContentTemplate"
Margin="2"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
...
</Style>
然后要么在 ListBox 的 ControlTemplate 中使用 ItemsPresenter,要么根本不设置 Template
属性:
<Style TargetType="ListBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Border BorderThickness="TemplateBinding BorderThickness"
BorderBrush="TemplateBinding BorderBrush"
Background="TemplateBinding Background">
<ScrollViewer Margin="2">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
...
</Style>
【讨论】:
以上是关于WPF Listbox 控件模板不显示 Listboxitem 控件模板和 ItemTemplate 数据模板的主要内容,如果未能解决你的问题,请参考以下文章
WPF 自定义列表筛选 自定义TreeView模板 自定义ListBox模板
〝WPF〞中的〝ListBox〞、〝ListView〞和〝DataGridView〞有啥区别?