WPF ListBox 图片选中问题续篇

8
在我的ListBox中,滚动图像和文本等的选择问题仍在继续。当我点击其中一个项目以选择它时,会运行一个进程打开Web浏览器并转到特定的URL。现在我遇到的问题是,当WPF应用程序失去焦点并且Web浏览器打开时,列表框中单击的项目会变白。这是整个ListBox XAML代码。我已将所选项目设置为透明,那么这是否与WPF应用程序失去焦点有关呢?
是否可以在运行打开Web浏览器的代码中添加一些内容来将焦点重新设置回WPF应用程序?
谢谢。
   <ListBox ItemsSource="{Binding Source={StaticResource WPFApparelCollection}}" Margin="61,-8,68,-18" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollBarVisibility="Hidden" SelectionMode="Single" x:Name="list1" MouseLeave="List1_MouseLeave" MouseMove="List1_MouseMove" Style="{DynamicResource ListBoxStyle1}" Background="Transparent" BorderThickness="0">
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Background" Value="Transparent" />
                <Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
                <Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
                <Setter Property="Padding" Value="20,10,20,10" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Border x:Name="Bd" SnapsToDevicePixels="true" Background="Transparent" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsSelected" Value="true">
                                    <Setter Property="Background" TargetName="Bd" Value="Transparent" />
                                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                                </Trigger>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="IsSelected" Value="true" />
                                        <Condition Property="Selector.IsSelectionActive" Value="false" />
                                    </MultiTrigger.Conditions>
                                    <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
                                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
                                </MultiTrigger>
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel Orientation="Horizontal" IsItemsHost="True" />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <Grid>
                        <Image Source="{Binding Image}" MouseLeave="Image_MouseLeave" MouseEnter="Image_MouseEnter" Cursor="Hand" Tag="{Binding Link}" MouseLeftButtonDown="Image_MouseLeftButtonDown"  VerticalAlignment="Top" HorizontalAlignment="Left"></Image>
                    </Grid>
                    <Label Content="{Binding Name}" Cursor="Hand" Tag="{Binding Link}" MouseLeftButtonDown="Label_MouseLeftButtonDown" VerticalAlignment="Bottom" Foreground="White" Style="{StaticResource Gotham-Medium}" FontSize="8pt" HorizontalAlignment="Center" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
1个回答

37

在使用ListBox选择颜色时,我发现一个技巧是使用系统画刷而不是与它们对抗。

当ListBox获得焦点并选择一个项目时,该项目的背景为SystemColors.HighlightBrush。然而,当ListBox失去焦点时,所选项目的背景变为SystemColors.ControlBrush。

知道了这一点,您可以重写该ListBox的系统画刷,以便其中的项目使用您想要的颜色绘制。

<ListBox>
    <ListBox.Resources>
        <!-- override the system brushes so that selected items are transparent
             whether the ListBox has focus or not -->
        <SolidColorBrush
            x:Key="{x:Static SystemColors.HighlightBrushKey}" 
            Color="Transparent" />
        <SolidColorBrush
            x:Key="{x:Static SystemColors.ControlBrushKey}" 
            Color="Transparent" />
        <SolidColorBrush
            x:Key="{x:Static SystemColors.HighlightTextBrushKey}" 
            Color="Black" />
    </ListBox.Resources>
    <!-- ... your items here ... -->
</ListBox>

哇...你太厉害了。这里的想法非常棒。我要开始考虑WPF,而不是Webform/Winform了。再次感谢。约翰 - John Batdorf
但是如果你的ListBox有上下文菜单,那么ContextMenu中的项目将没有高亮显示,对吧?我怎样才能实现两种行为? - jpsstavares
@jpsstavares 是的,上下文菜单在技术上并不属于与其所有者相同的可视树,因此画刷无法继承。你可能需要在上下文菜单的资源中复制它们,尽管我没有尝试过。 - Matt Hamilton
我遇到了这种行为,所以我重新定义了ContextMenu资源中的HighlightBrushKey。 - jpsstavares

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接