我在 ItemTemplate 中有一个带有扩展器的列表框。我成功地将扩展器的 IsExpanded 属性绑定(bind)到 ListBoxItem 的 IsSelected 属性。现在我想将样式应用到也绑定(bind)到 IsSelected 属性的 ListBoxItem 内容。
<ListBox.ItemTemplate>
<DataTemplate>
<Border Name="myBorder">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Description}" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="Date:"/>
<TextBlock Text="{Binding Date}"/>
</StackPanel>
<dx:DXExpander Name="expanderDetails"
IsExpanded="{Binding Mode=TwoWay, Path=IsSelected,
RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Count:"/>
<TextBlock Text="{Binding Count}"/>
</StackPanel>
</dx:DXExpander>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
我想要做的是以某种方式将“myBorder”边框的样式设置为“NotSelectedBorderStyle”(对于未选择的ListBoxItems),以及为“SelectedBorderStyle”对于SelectedItem(具有单选的ListBox)。
仅供引用,样式定义了背景、边框之类的东西,只是为了清楚地表明选择了哪个项目,这些样式没有什么花哨的。
我尝试了 accepted answer here但如果我完全切换样式,我就会失去 DXExpander 所拥有的漂亮的扩展动画。
我想一定有一些使用触发器的解决方案,但我不能只是击中正确的位置。
最佳答案
终于我明白了,我将其发布在这里,希望这会节省其他人的时间和痛苦:-P
这段代码做了一些额外的事情:EventSetter 和相应的 Handler 方法用于捕获对 DataTemplate 内元素的点击,以便选择包含该元素的 ListBoxItem(如果不这样做,您可能会在其中键入文本)一个项目,而选择了另一个项目)。
内部边框(“myBorder”)只是堆栈面板的容器,我必须将所有内容包装在另一个边框(“backgroundBorder”)内,当选择 ListBoxItem 时,该边框会更改样式。
<Style x:Key="FocusedContainer" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="LightGray"/>
<EventSetter Event="GotKeyboardFocus" Handler="OnListBoxItemContainerFocused" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="backgroundBorder" Width="Auto" Style="{StaticResource NotSelectedBorderStyle}">
<ContentPresenter Content="{TemplateBinding Content}">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<Border Name="myBorder">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Description}" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="Date:"/>
<TextBlock Text="{Binding Date}"/>
</StackPanel>
<dx:DXExpander Name="expanderDetails"
IsExpanded="{Binding Mode=TwoWay, Path=IsSelected,
RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Count:"/>
<TextBlock Text="{Binding Count}"/>
</StackPanel>
</dx:DXExpander>
</StackPanel>
</Border>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="backgroundBorder" Property="Style" Value="{StaticResource SelectedBorderStyle}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
然后我将 ListBox 中的 ItemContainerStyle 设置为上述样式:
<ListBox Background="#7FFFFFFF" HorizontalContentAlignment="Stretch"
ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True"
ItemContainerStyle="{StaticResource FocusedContainer}"/>
最后,GotKeyBoardFocus 处理程序背后的代码:
private void OnListBoxItemContainerFocused(object sender, RoutedEventArgs e)
{
(sender as ListBoxItem).IsSelected = true;
}
代码困惑,但用户界面非常整洁。希望这对某人有帮助!
关于wpf - 如果选择了该项目,则更改 ListBoxItem 中的 DataTemplate 样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14542682/