【问题标题】:Change DataTemplate style in ListBoxItem if the item is selected如果项目被选中,则更改 ListBoxItem 中的 DataTemplate 样式
【发布时间】:2013-01-26 23:32:10
【问题描述】:

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

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

我尝试了accepted answer here,但如果我完全切换样式,我会失去我的 DXExpander 拥有的漂亮的扩展动画。

我想肯定有一些使用触发器的解决方案,但我不能只是击中正确的位置。

【问题讨论】:

    标签: wpf xaml triggers listbox styles


    【解决方案1】:

    我终于明白了,我把它贴在这里,希望这样可以节省别人的时间和痛苦:-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 相当整洁。希望这对某人有帮助!

    【讨论】:

      猜你喜欢
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-07
      • 2019-12-23
      • 1970-01-01
      相关资源
      最近更新 更多