如果选中该项,则在ListBoxItem中更改DataTemplate样式

时间:2013-01-26 23:32:11

标签: wpf xaml triggers listbox styles

我在ItemTemplate中有一个带扩展器的列表框。我设法将扩展器的IsExpanded属性绑定到ListBoxItem的IsSelected属性ok。现在我想将一个样式应用于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”边框的样式设置为未选择的ListBoxItems的“NotSelectedBorderStyle”,并为SelectedItem设置“SelectedBorderStyle”(带有单个选择的ListBox)。

仅供参考,样式定义了背景,边框和那种东西,只是为了清楚选择哪个项目,这些样式没什么特别的。

我尝试了accepted answer here,但是如果我完全切换样式,我会松开DXExpander的漂亮动画。

我想必须有一些使用触发器的解决方案,但我不能只是找到正确的位置。

1 个答案:

答案 0 :(得分:4)

最后我明白了,我在这里张贴,希望这能节省别人的时间和痛苦:-P

这段代码做了一些额外的事情:EventSetter和相应的Handler方法用于捕获DataTemplate内部元素的点击,以便选择包含元素的ListBoxItem(如果你不这样做,你可以在里面输入文本一个项目,而选择了另一个项目。)

内部边框(“myBorder”)只是stackpanels的容器,我必须将所有内容包装在另一个边框(“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中非常整洁。希望这有助于某人!