2

我在 ItemTemplate 中有一个带有扩展器的列表框。我设法将扩展器的 IsExpanded 属性绑定到 ListBoxItem 的 IsSelected 属性确定。现在我想将样式应用于 ListBoxItem 的内容,该内容也绑定到 IsSelected 属性。

    <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)。

仅供参考,样式定义了背景,边框和那种东西,只是为了明确选择了哪个项目,这些样式没有什么花哨的。

我在这里尝试了接受的答案,但如果我完全切换样式,我会失去我的 DXExpander 拥有的漂亮的扩展动画。

我想一定有一些使用触发器的解决方案,但我不能只打对了位置。

4

1 回答 1

4

终于我明白了,我把它贴在这里,希望这能节省别人的时间和痛苦:-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;
    }

代码乱七八糟,但 UI 很整洁。希望这对某人有帮助!

于 2013-01-27T01:17:47.420 回答