将自定义 ListBox 与自定义 ListBoxItem 一起使用时如何保留 TemplateBindings
How to keep TemplateBindings when using a Custom ListBox with a Custom ListBoxItem
我想在自定义 ListBox 中使用我的自定义 ListBoxItem,并希望在绑定到 ItemSource 时能够在 ListBox DataTemplate 中绑定我自己的属性。
我对此一无所知。我发现的组合总是在 Xaml 声明的 ItemContainerStyle 或 ItemTemplate 样式中,但没有任何自定义 Classes 接近我的情况。也许我做错了什么?
自定义列表框Class:
public class WPM_ListBox : ListBox
{
protected override bool IsItemItsOwnContainerOverride(object item)
{
return (item is WPM_ListBoxItem);
}
protected override DependencyObject GetContainerForItemOverride()
{
return new WPM_ListBoxItem();
}
public WPM_ListBox()
{
this.DefaultStyleKey = typeof(WPM_ListBox);
}
static WPM_ListBox()
{
}
}
这是 WPM_ListBoxItem Class 的简短版本:
public class WPM_ListBoxItem : ListBoxItem
{
public WPM_ListBoxItem()
{
this.DefaultStyleKey = typeof(WPM_ListBoxItem);
}
static WPM_ListBoxItem()
{
BackgroundProperty.OverrideMetadata(typeof(WPM_ListBoxItem),
new FrameworkPropertyMetadata((SolidColorBrush)(new BrushConverter().ConvertFrom("#66767A"))));
}
public string WPM_HeaderContent
{
get { return (string)GetValue(WPM_HeaderContentProperty); }
set { SetValue(WPM_HeaderContentProperty, value); }
}
public static readonly DependencyProperty WPM_HeaderContentProperty =
DependencyProperty.Register("WPM_HeaderContent", typeof(string),
typeof(WPM_ListBoxItem), new PropertyMetadata("WPM_HeaderContent"));
}
这里是 Generic.xaml:
<Style x:Key="ItemStyle" TargetType="local:WPM_ListBoxItem" >
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Foreground" Value="#E9EEEE" x:Name="foreground"/>
<Setter Property="IsHitTestVisible" Value="True"/>
<Setter Property="Background" Value="Transparent" x:Name="Background_Property"/>
<Setter Property="BorderBrush" Value="#67767A"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:WPM_ListBoxItem" >
<local:WPM_Border IsHitTestVisible="True" Background="Transparent" Margin="1" VerticalAlignment="Top" x:Name="border" Theme="grau" BorderThickness5="1 1 0 0" BorderThickness4="1 1 0 0" BorderThickness3="1 1 0 0" BorderThickness2="1 1 0 0" BorderThickness1="1 1 0 0" >
<local:WPM_Border.Data>
<Grid x:Name="grid" IsHitTestVisible="True" Background="Transparent" Margin="0" >
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="45" Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="row1" />
<RowDefinition x:Name="row2" />
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Top" FontFamily="Arial" FontWeight="Normal" FontSize="{TemplateBinding WPM_HeaderContenFontSize}" Margin="{TemplateBinding WPM_HeaderContentMargin}" Text="{TemplateBinding WPM_HeaderContent}" Foreground="{TemplateBinding WPM_HeaderContentBrush}" Padding="0 2 0 0" x:Name="headercontent" Grid.ColumnSpan="2" ScrollViewer.CanContentScroll="False"/>
<!--<ContentPresenter />-->
<StackPanel Margin="3 3 0 0" Grid.Row="1" x:Name="stackpanel1" >
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Top" FontWeight="Normal" FontSize="{TemplateBinding WPM_LabelDescriptionFontSize}" Margin="{TemplateBinding WPM_LabelDescriptionMargin}" Text="{TemplateBinding WPM_LabelDescription1}" Foreground="{TemplateBinding WPM_LabelDescriptionBrush1}"/>
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Top" FontWeight="Normal" FontSize="{TemplateBinding WPM_LabelDescriptionFontSize}" Margin="{TemplateBinding WPM_LabelDescriptionMargin}" Text="{TemplateBinding WPM_LabelDescription2}" Foreground="{TemplateBinding WPM_LabelDescriptionBrush2}"/>
</StackPanel>
<StackPanel Margin="3 3 0 0" Grid.Row="1" Grid.Column="1" x:Name="stackpanel2" >
<TextBlock VerticalAlignment="Top" FontWeight="Normal" FontSize="{TemplateBinding WPM_LabelContentFontSize}" HorizontalAlignment="Left" Margin="{TemplateBinding WPM_LabelContentMargin}" Text="{TemplateBinding WPM_LabelContent1}" Foreground="{TemplateBinding WPM_LabelContentBrush1}"/>
<TextBlock VerticalAlignment="Top" FontWeight="Normal" FontSize="{TemplateBinding WPM_LabelContentFontSize}" HorizontalAlignment="Left" Margin="{TemplateBinding WPM_LabelContentMargin}" Text="{TemplateBinding WPM_LabelContent2}" Foreground="{TemplateBinding WPM_LabelContentBrush2}"/>
</StackPanel>
</Grid>
</local:WPM_Border.Data>
</local:WPM_Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="row2" Property="Height" Value="Auto"/>
<Setter TargetName="border" Property="Height" Value="Auto"/>
<Setter Property="Height" Value="Auto"/>
<Setter TargetName="border" Property="BorderThickness1" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness2" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness3" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness4" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness5" Value="1 1 0 0"/>
<Setter TargetName="headercontent" Property="Padding" Value="3 2 0 0"/>
</Trigger>
<Trigger Property="IsSelected" Value="false">
<Setter TargetName="row2" Property="Height" Value="0"/>
<Setter TargetName="border" Property="Height" Value="35"/>
<Setter Property="Height" Value="35"/>
<Setter TargetName="border" Property="BorderThickness1" Value="0"/>
<Setter TargetName="border" Property="BorderThickness2" Value="0"/>
<Setter TargetName="border" Property="BorderThickness3" Value="0"/>
<Setter TargetName="border" Property="BorderThickness4" Value="0"/>
<Setter TargetName="border" Property="BorderThickness5" Value="0"/>
<Setter TargetName="headercontent" Property="Padding" Value="0 2 0 0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BoxStyle" TargetType="local:WPM_ListBox">
<Setter Property="Padding" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="Once"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:WPM_ListBox">
<Grid>
<ScrollViewer x:Name="PART_ScrollViewer"
IsTabStop="False"
Margin="0"
>
<ItemsPresenter/>
</ScrollViewer>
<ContentPresenter x:Name="PART_DropVisualPlaceholder" Visibility="Collapsed" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle" Value="{StaticResource ItemStyle}"></Setter>
</Style>
<Style TargetType="local:WPM_ListBoxItem" BasedOn="{StaticResource ItemStyle}"/>
<Style TargetType="local:WPM_ListBox" BasedOn="{StaticResource BoxStyle}"/>
在 Xaml 中我想这样使用它:
<local:WPM_ListBox ItemsSource="{Binding RoutenListe}" Grid.Row="1" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" BorderThickness="0" Margin="0" Padding="0" Background="#32557B" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" >
<local:WPM_ListBox.ItemTemplate >
<DataTemplate >
<local:WPM_ListBoxItem WPM_HeaderContent="{Binding Name}"
WPM_LabelContent1="{Binding Startort}" WPM_LabelContent2="{Binding Zielort}"
Background="Transparent" WPM_HeaderContentMargin="6 2 0 0" WPM_HeaderContenFontSize="24" WPM_LabelContentMargin="3 -4 0 3"
WPM_LabelDescription1="Start:" WPM_LabelDescription2="Ziel:" WPM_LabelDescriptionMargin="10 -4 0 3" />
</DataTemplate>
</local:WPM_ListBox.ItemTemplate>
</local:WPM_ListBox>
我知道我可以用 ContentPresenter 替换声明的控件,然后简单地使用 DataTemplate 中的标签或其他东西。但这不是依赖关系的目的吗?
如果我使用标准 ListBox 并在 DataTemplate 中使用自定义 ListBoxItem,则会显示我的数据(绑定数据),但 "IsSelected" 触发器不再工作。如果我将我的自定义 ListBox 与 DataTemplate 中声明的自定义 ListBoxItem 一起使用,则只显示我声明的属性(声明的 DependencyProperties 中的标准值)而没有绑定,但 IsSelected 属性 有效。
我什至尝试将所有背景属性设置为透明,以确保 HitTest 不会失败。
我错过了什么吗?
您使用的 ItemTemplate
有误。 ItemTemplate
用于为 ListBoxItem 的内容提供模板,因此它不应包含 ListBoxItem。
选项 1
从您的视图中删除 ItemTemplate
:
<local:WPM_ListBox ItemsSource="{Binding RoutenListe}"
Grid.Row="1"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderThickness="0" Margin="0" Padding="0"
Background="#32557B"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto" />
因为你已经做到了,所以 WPM_ListBox
使用 WPM_ListBoxItem
作为它的默认项目容器,并且你已经设置了 ItemContainerStyle
,它会自动生成它们并且样式将自动应用于它们。
编辑 2: 问题是您的 WPM_ListBox
有一系列属性在这种情况下没有人设置,因此它们保持默认值。为了设置这些属性,您可以再次使用 ItemContainerStyle
,并使用 Bindings:
将属性绑定到 DataContext 中的值
<local:WPM_ListBox ItemsSource="{Binding RoutenListe}"
Grid.Row="1"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderThickness="0" Margin="0" Padding="0"
Background="#32557B"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<local:WPM_ListBox.ItemContainerStyle>
<Style TargetType="{x:Type local:WPM_ListBoxItem}"
BasedOn="{StaticResource ItemStyle}">
<Setter Property="WPM_HeaderContent"
Value="{Binding Name}" />
<Setter Property="WPM_LabelContent1"
Value="{Binding Startort}" />
<!-- Etc. -->
</Style>
</local:WPM_ListBox.ItemContainerStyle>
</local:WPM_ListBox>
(编辑: 如果您想自定义某些特定项目的内容,您需要在 WPM_ListBoxItem
中使用 ContentPresenter
' s 模板,然后使用 ItemTemplate
指定您希望如何在该特定列的 ContentPresenter
中显示数据)
选项 2
不要覆盖 ListBox
的默认项目容器,而是使用您的 WPM_ListBoxItem
作为常规 ContentControl
或类似的东西,并将其添加到 ItemTemplate
您的 ListBox
,将 Triggers
更改为 DataTriggers
绑定到实际 ListBoxItem
的 IsSelected
属性(这是由ListBox,现在)。
WPM_ListBoxItem.cs:
public class WPM_ListBoxItem : ContentControl
{
...
}
您的 WPM_ListBoxItem
风格触发器:
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Value="true">
<Setter TargetName="row2" Property="Height" Value="Auto"/>
<Setter TargetName="border" Property="Height" Value="Auto"/>
<Setter Property="Height" Value="Auto"/>
<Setter TargetName="border" Property="BorderThickness1" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness2" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness3" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness4" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness5" Value="1 1 0 0"/>
<Setter TargetName="headercontent" Property="Padding" Value="3 2 0 0"/>
</Trigger>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Value="false">
<Setter TargetName="row2" Property="Height" Value="0"/>
<Setter TargetName="border" Property="Height" Value="35"/>
<Setter Property="Height" Value="35"/>
<Setter TargetName="border" Property="BorderThickness1" Value="0"/>
<Setter TargetName="border" Property="BorderThickness2" Value="0"/>
<Setter TargetName="border" Property="BorderThickness3" Value="0"/>
<Setter TargetName="border" Property="BorderThickness4" Value="0"/>
<Setter TargetName="border" Property="BorderThickness5" Value="0"/>
<Setter TargetName="headercontent" Property="Padding" Value="0 2 0 0"/>
</Trigger>
</ControlTemplate.Triggers>
您的观点XAML:
<ListBox ItemsSource="{Binding RoutenListe}" Grid.Row="1" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" BorderThickness="0" Margin="0" Padding="0" Background="#32557B" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto">
<local:WPM_ListBox.ItemTemplate>
<DataTemplate>
<local:WPM_ListBoxItem WPM_HeaderContent="{Binding Name}"
WPM_LabelContent1="{Binding Startort}" WPM_LabelContent2="{Binding Zielort}"
Background="Transparent" WPM_HeaderContentMargin="6 2 0 0" WPM_HeaderContenFontSize="24" WPM_LabelContentMargin="3 -4 0 3"
WPM_LabelDescription1="Start:" WPM_LabelDescription2="Ziel:" WPM_LabelDescriptionMargin="10 -4 0 3" />
</DataTemplate>
</local:WPM_ListBox.ItemTemplate>
</ListBox>
我想在自定义 ListBox 中使用我的自定义 ListBoxItem,并希望在绑定到 ItemSource 时能够在 ListBox DataTemplate 中绑定我自己的属性。
我对此一无所知。我发现的组合总是在 Xaml 声明的 ItemContainerStyle 或 ItemTemplate 样式中,但没有任何自定义 Classes 接近我的情况。也许我做错了什么?
自定义列表框Class:
public class WPM_ListBox : ListBox
{
protected override bool IsItemItsOwnContainerOverride(object item)
{
return (item is WPM_ListBoxItem);
}
protected override DependencyObject GetContainerForItemOverride()
{
return new WPM_ListBoxItem();
}
public WPM_ListBox()
{
this.DefaultStyleKey = typeof(WPM_ListBox);
}
static WPM_ListBox()
{
}
}
这是 WPM_ListBoxItem Class 的简短版本:
public class WPM_ListBoxItem : ListBoxItem
{
public WPM_ListBoxItem()
{
this.DefaultStyleKey = typeof(WPM_ListBoxItem);
}
static WPM_ListBoxItem()
{
BackgroundProperty.OverrideMetadata(typeof(WPM_ListBoxItem),
new FrameworkPropertyMetadata((SolidColorBrush)(new BrushConverter().ConvertFrom("#66767A"))));
}
public string WPM_HeaderContent
{
get { return (string)GetValue(WPM_HeaderContentProperty); }
set { SetValue(WPM_HeaderContentProperty, value); }
}
public static readonly DependencyProperty WPM_HeaderContentProperty =
DependencyProperty.Register("WPM_HeaderContent", typeof(string),
typeof(WPM_ListBoxItem), new PropertyMetadata("WPM_HeaderContent"));
}
这里是 Generic.xaml:
<Style x:Key="ItemStyle" TargetType="local:WPM_ListBoxItem" >
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Foreground" Value="#E9EEEE" x:Name="foreground"/>
<Setter Property="IsHitTestVisible" Value="True"/>
<Setter Property="Background" Value="Transparent" x:Name="Background_Property"/>
<Setter Property="BorderBrush" Value="#67767A"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:WPM_ListBoxItem" >
<local:WPM_Border IsHitTestVisible="True" Background="Transparent" Margin="1" VerticalAlignment="Top" x:Name="border" Theme="grau" BorderThickness5="1 1 0 0" BorderThickness4="1 1 0 0" BorderThickness3="1 1 0 0" BorderThickness2="1 1 0 0" BorderThickness1="1 1 0 0" >
<local:WPM_Border.Data>
<Grid x:Name="grid" IsHitTestVisible="True" Background="Transparent" Margin="0" >
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="45" Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="row1" />
<RowDefinition x:Name="row2" />
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Top" FontFamily="Arial" FontWeight="Normal" FontSize="{TemplateBinding WPM_HeaderContenFontSize}" Margin="{TemplateBinding WPM_HeaderContentMargin}" Text="{TemplateBinding WPM_HeaderContent}" Foreground="{TemplateBinding WPM_HeaderContentBrush}" Padding="0 2 0 0" x:Name="headercontent" Grid.ColumnSpan="2" ScrollViewer.CanContentScroll="False"/>
<!--<ContentPresenter />-->
<StackPanel Margin="3 3 0 0" Grid.Row="1" x:Name="stackpanel1" >
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Top" FontWeight="Normal" FontSize="{TemplateBinding WPM_LabelDescriptionFontSize}" Margin="{TemplateBinding WPM_LabelDescriptionMargin}" Text="{TemplateBinding WPM_LabelDescription1}" Foreground="{TemplateBinding WPM_LabelDescriptionBrush1}"/>
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Top" FontWeight="Normal" FontSize="{TemplateBinding WPM_LabelDescriptionFontSize}" Margin="{TemplateBinding WPM_LabelDescriptionMargin}" Text="{TemplateBinding WPM_LabelDescription2}" Foreground="{TemplateBinding WPM_LabelDescriptionBrush2}"/>
</StackPanel>
<StackPanel Margin="3 3 0 0" Grid.Row="1" Grid.Column="1" x:Name="stackpanel2" >
<TextBlock VerticalAlignment="Top" FontWeight="Normal" FontSize="{TemplateBinding WPM_LabelContentFontSize}" HorizontalAlignment="Left" Margin="{TemplateBinding WPM_LabelContentMargin}" Text="{TemplateBinding WPM_LabelContent1}" Foreground="{TemplateBinding WPM_LabelContentBrush1}"/>
<TextBlock VerticalAlignment="Top" FontWeight="Normal" FontSize="{TemplateBinding WPM_LabelContentFontSize}" HorizontalAlignment="Left" Margin="{TemplateBinding WPM_LabelContentMargin}" Text="{TemplateBinding WPM_LabelContent2}" Foreground="{TemplateBinding WPM_LabelContentBrush2}"/>
</StackPanel>
</Grid>
</local:WPM_Border.Data>
</local:WPM_Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="row2" Property="Height" Value="Auto"/>
<Setter TargetName="border" Property="Height" Value="Auto"/>
<Setter Property="Height" Value="Auto"/>
<Setter TargetName="border" Property="BorderThickness1" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness2" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness3" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness4" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness5" Value="1 1 0 0"/>
<Setter TargetName="headercontent" Property="Padding" Value="3 2 0 0"/>
</Trigger>
<Trigger Property="IsSelected" Value="false">
<Setter TargetName="row2" Property="Height" Value="0"/>
<Setter TargetName="border" Property="Height" Value="35"/>
<Setter Property="Height" Value="35"/>
<Setter TargetName="border" Property="BorderThickness1" Value="0"/>
<Setter TargetName="border" Property="BorderThickness2" Value="0"/>
<Setter TargetName="border" Property="BorderThickness3" Value="0"/>
<Setter TargetName="border" Property="BorderThickness4" Value="0"/>
<Setter TargetName="border" Property="BorderThickness5" Value="0"/>
<Setter TargetName="headercontent" Property="Padding" Value="0 2 0 0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BoxStyle" TargetType="local:WPM_ListBox">
<Setter Property="Padding" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="Once"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:WPM_ListBox">
<Grid>
<ScrollViewer x:Name="PART_ScrollViewer"
IsTabStop="False"
Margin="0"
>
<ItemsPresenter/>
</ScrollViewer>
<ContentPresenter x:Name="PART_DropVisualPlaceholder" Visibility="Collapsed" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle" Value="{StaticResource ItemStyle}"></Setter>
</Style>
<Style TargetType="local:WPM_ListBoxItem" BasedOn="{StaticResource ItemStyle}"/>
<Style TargetType="local:WPM_ListBox" BasedOn="{StaticResource BoxStyle}"/>
在 Xaml 中我想这样使用它:
<local:WPM_ListBox ItemsSource="{Binding RoutenListe}" Grid.Row="1" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" BorderThickness="0" Margin="0" Padding="0" Background="#32557B" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" >
<local:WPM_ListBox.ItemTemplate >
<DataTemplate >
<local:WPM_ListBoxItem WPM_HeaderContent="{Binding Name}"
WPM_LabelContent1="{Binding Startort}" WPM_LabelContent2="{Binding Zielort}"
Background="Transparent" WPM_HeaderContentMargin="6 2 0 0" WPM_HeaderContenFontSize="24" WPM_LabelContentMargin="3 -4 0 3"
WPM_LabelDescription1="Start:" WPM_LabelDescription2="Ziel:" WPM_LabelDescriptionMargin="10 -4 0 3" />
</DataTemplate>
</local:WPM_ListBox.ItemTemplate>
</local:WPM_ListBox>
我知道我可以用 ContentPresenter 替换声明的控件,然后简单地使用 DataTemplate 中的标签或其他东西。但这不是依赖关系的目的吗?
如果我使用标准 ListBox 并在 DataTemplate 中使用自定义 ListBoxItem,则会显示我的数据(绑定数据),但 "IsSelected" 触发器不再工作。如果我将我的自定义 ListBox 与 DataTemplate 中声明的自定义 ListBoxItem 一起使用,则只显示我声明的属性(声明的 DependencyProperties 中的标准值)而没有绑定,但 IsSelected 属性 有效。
我什至尝试将所有背景属性设置为透明,以确保 HitTest 不会失败。
我错过了什么吗?
您使用的 ItemTemplate
有误。 ItemTemplate
用于为 ListBoxItem 的内容提供模板,因此它不应包含 ListBoxItem。
选项 1
从您的视图中删除 ItemTemplate
:
<local:WPM_ListBox ItemsSource="{Binding RoutenListe}"
Grid.Row="1"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderThickness="0" Margin="0" Padding="0"
Background="#32557B"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto" />
因为你已经做到了,所以 WPM_ListBox
使用 WPM_ListBoxItem
作为它的默认项目容器,并且你已经设置了 ItemContainerStyle
,它会自动生成它们并且样式将自动应用于它们。
编辑 2: 问题是您的 WPM_ListBox
有一系列属性在这种情况下没有人设置,因此它们保持默认值。为了设置这些属性,您可以再次使用 ItemContainerStyle
,并使用 Bindings:
<local:WPM_ListBox ItemsSource="{Binding RoutenListe}"
Grid.Row="1"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderThickness="0" Margin="0" Padding="0"
Background="#32557B"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<local:WPM_ListBox.ItemContainerStyle>
<Style TargetType="{x:Type local:WPM_ListBoxItem}"
BasedOn="{StaticResource ItemStyle}">
<Setter Property="WPM_HeaderContent"
Value="{Binding Name}" />
<Setter Property="WPM_LabelContent1"
Value="{Binding Startort}" />
<!-- Etc. -->
</Style>
</local:WPM_ListBox.ItemContainerStyle>
</local:WPM_ListBox>
(编辑: 如果您想自定义某些特定项目的内容,您需要在 WPM_ListBoxItem
中使用 ContentPresenter
' s 模板,然后使用 ItemTemplate
指定您希望如何在该特定列的 ContentPresenter
中显示数据)
选项 2
不要覆盖 ListBox
的默认项目容器,而是使用您的 WPM_ListBoxItem
作为常规 ContentControl
或类似的东西,并将其添加到 ItemTemplate
您的 ListBox
,将 Triggers
更改为 DataTriggers
绑定到实际 ListBoxItem
的 IsSelected
属性(这是由ListBox,现在)。
WPM_ListBoxItem.cs:
public class WPM_ListBoxItem : ContentControl
{
...
}
您的 WPM_ListBoxItem
风格触发器:
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Value="true">
<Setter TargetName="row2" Property="Height" Value="Auto"/>
<Setter TargetName="border" Property="Height" Value="Auto"/>
<Setter Property="Height" Value="Auto"/>
<Setter TargetName="border" Property="BorderThickness1" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness2" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness3" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness4" Value="1 1 0 0"/>
<Setter TargetName="border" Property="BorderThickness5" Value="1 1 0 0"/>
<Setter TargetName="headercontent" Property="Padding" Value="3 2 0 0"/>
</Trigger>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Value="false">
<Setter TargetName="row2" Property="Height" Value="0"/>
<Setter TargetName="border" Property="Height" Value="35"/>
<Setter Property="Height" Value="35"/>
<Setter TargetName="border" Property="BorderThickness1" Value="0"/>
<Setter TargetName="border" Property="BorderThickness2" Value="0"/>
<Setter TargetName="border" Property="BorderThickness3" Value="0"/>
<Setter TargetName="border" Property="BorderThickness4" Value="0"/>
<Setter TargetName="border" Property="BorderThickness5" Value="0"/>
<Setter TargetName="headercontent" Property="Padding" Value="0 2 0 0"/>
</Trigger>
</ControlTemplate.Triggers>
您的观点XAML:
<ListBox ItemsSource="{Binding RoutenListe}" Grid.Row="1" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" BorderThickness="0" Margin="0" Padding="0" Background="#32557B" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto">
<local:WPM_ListBox.ItemTemplate>
<DataTemplate>
<local:WPM_ListBoxItem WPM_HeaderContent="{Binding Name}"
WPM_LabelContent1="{Binding Startort}" WPM_LabelContent2="{Binding Zielort}"
Background="Transparent" WPM_HeaderContentMargin="6 2 0 0" WPM_HeaderContenFontSize="24" WPM_LabelContentMargin="3 -4 0 3"
WPM_LabelDescription1="Start:" WPM_LabelDescription2="Ziel:" WPM_LabelDescriptionMargin="10 -4 0 3" />
</DataTemplate>
</local:WPM_ListBox.ItemTemplate>
</ListBox>