【问题标题】:How to Get Rid of Border around ListBox Selected Item in WPF?如何摆脱 WPF 中列表框选定项周围的边框?
【发布时间】:2019-06-10 01:06:38
【问题描述】:

我有一个装满苹果的 ListBox。我想将所选项目更改为仅具有无边框的纯色背景。我遵循了这个建议:

Question #146269: Change Wpf Datatemplate for Listbox Item if Selected

这是我的 xaml:

<UserControl.Resources>
    <ResourceDictionary>
        <DataTemplate x:Key="AppleItemTemplate">
            <Border Opacity="1" Padding="10,5">
                    <TextBlock Foreground="{DynamicResource PrimaryTextColor}">
                    <TextBlock.Text>
                        <Binding Path="DisplayName"/>
                    </TextBlock.Text>
                </TextBlock>
            </Border>
        </DataTemplate>
        <DataTemplate x:Key="AppleItemTemplateSelected">
            <Border BorderThickness="0" BorderBrush="Transparent" Padding="10,5" Background="{DynamicResource LeftSidebarBGColorHighlight}">
                <TextBlock Foreground="{DynamicResource PrimaryTextColor}">
                    <TextBlock.Text>
                        <Binding Path="DisplayName"/>
                    </TextBlock.Text>
                </TextBlock>
            </Border>
        </DataTemplate>
        <Style TargetType="{x:Type ListBoxItem}" x:Key="AppleContainerStyle">
            <Setter Property="ContentTemplate" Value="{DynamicResource AppleItemTemplate}"/>
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="ContentTemplate" Value="{DynamicResource AppleItemTemplateSelected}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ResourceDictionary>
</UserControl.Resources>

<ListBox ItemsSource="{Binding Apples}"
         SelectedItem="{Binding SelectedApple}"
         ItemContainerStyle="{StaticResource AppleContainerStyle}"

         Background="{DynamicResource LeftSidebarBGColor}"
         BorderThickness="0"
         ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalContentAlignment="Stretch"
         >

    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

当我运行程序并选择一个苹果时,我得到了这个:

您可以看到 XAML 正在应用灰色背景颜色。但是有一个不应该存在的白色边框。如果仔细观察,在边框内的盒子左右两侧也有细微的灰色带。 (悲伤的脸)

有人知道我的数据模板或列表框设置有什么问题吗?

【问题讨论】:

    标签: wpf xaml listbox


    【解决方案1】:

    如果你只是想删除选定项目的边框,试试这个:

    在触发器“IsSelected”中添加&lt;Setter Property="BorderThickness" Value="0"/&gt;

    在我的演示中,我发现它有效。

    【讨论】:

    • 这行得通,但它有点小技巧,因为边框元素仍然存在。发生的事情是 ItemListBox 使用包含边框和 ContentPresenter 的模板,并且您正在为 ContentPresenter 设置要使用的数据模板,即包装器仍然存在。您需要做的是将 DataTemplates 更改为 ControlTemplates 并设置 ListBoxItem 样式的“Template”属性而不是“ContentTemplate”。
    • 这是一个微妙的区别,但很重要。以自定义按钮为例。一般来说,您希望能够指定整体外观,即边框粗细、突出显示颜色等,并且所有按钮都是相同的。另一方面,该按钮内的内容可能是各种不同的东西...文本、图像、控件集合等,您希望内容呈现的方式将由按钮的 Content 属性的数据决定绑定到。按钮的整体外观由 ContentControl 控制,内容由 DataTemplates 控制。
    • 我认为有时会出现混淆,因为人们只需要一个 DataTemplate,因为他们只呈现一种类型的数据。在这种情况下是的,您通常可以通过覆盖 ControlTemplate 或 DataTemplate 来获得完全相同的结果。但是 DataTemplates 所做的是允许您创建一个可以通过指定多个 DataTemplates 来呈现许多不同类型的数据的单个控件,每个类型一个。而且您可以做到这一点,而无需从头开始为每种类型重新创建整个控件。
    • 这是一件棘手的事情,因为我们在 WinForms 或 MFC 等中从未有过这种级别的控制。WPF 所做的是提供更高级别的自定义,但如果设计不佳,它可以创建GUI 开发人员需要做更多的工作。一旦您的界面开始变得更加复杂和更加受数据驱动,ControlTemplate/DataTemplate 范例可以为您节省大量时间和工作量。
    • @MarkFeldman 所以,听起来同时使用 ControlTemplate 和 DataTemplate 可能是合适的,对吗?例如,如果您想使用控件模板创建通用按钮样式,但随后该按钮的不同实例使用不同的数据模板显示不同类型的数据。对吗?
    【解决方案2】:

    MarkFeldman 的回答有效,但存在鼠标单击事件问题。使用 Border 元素上的 Padding,当单击文本项之间的填充区域时,鼠标单击不会注册。为了解决这个问题,我用 StackPanel 替换了 Border,并将 Padding 移到了 TextBlock 上。文本块本身的填充正确地注册了一次点击。

    最终结果:

    <UserControl.Resources>
    <ResourceDictionary>
        <ControlTemplate x:Key="AppleItemTemplate">
            <StackPanel Opacity="1">
                    <TextBlock Padding="10,5" Foreground="{DynamicResource PrimaryTextColor}">
                    <TextBlock.Text>
                        <Binding Path="DisplayName"/>
                    </TextBlock.Text>
                </TextBlock>
            </StackPanel>
        </ControlTemplate>
        <ControlTemplate x:Key="AppleItemTemplateSelected">
            <StackPanel Background="{DynamicResource LeftSidebarBGColorHighlight}">
                <TextBlock Padding="10,5" Foreground="{DynamicResource PrimaryTextColor}">
                    <TextBlock.Text>
                        <Binding Path="DisplayName"/>
                    </TextBlock.Text>
                </TextBlock>
            </StackPanel>
        </ControlTemplate>
        <Style TargetType="{x:Type ListBoxItem}" x:Key="AppleContainerStyle">
            <Setter Property="Template" Value="{DynamicResource AppleItemTemplate}"/>
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Template" Value="{DynamicResource AppleItemTemplateSelected}"/>
                    <Setter Property="BorderThickness" Value="0"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ResourceDictionary>
    

    【讨论】: