【问题标题】:Disable Selection or Focus on Listbox Items禁用选择或关注列表框项目
【发布时间】:2014-04-22 22:21:55
【问题描述】:

我有一个 WPF 应用程序,其中包含动态生成的列表框项。我想禁用列表框项目的选择或“可聚焦性”,而不禁用每个列表框项目中的所有控件(它们包含用户需要能够与之交互的按钮和链接)。下面是我试图阻止的图片:

这张图片显示了两个列表框项目。我点击了顶部列表框项目的背景区域并选择了它,这使文本更难阅读并且在视觉上没有吸引力。

【问题讨论】:

  • 如果你不想选择,那么你可以使用一个简单的 ItemsControl 并在其样式中添加一个 ScrollViewer。
  • dynamically generated listbox items 听起来真的很奇怪,而且太winforms。您应该使用 DataBinding,是的,正如 @Didier 所说,您需要 ItemsControl 而不是 ListBox。
  • 我可能使用了错误的术语。列表框项通过可观察集合上的数据绑定呈现。
  • 我已经实现了 ItemsControl 而不是 Listbox 并且它确实禁用了选择 - 但是它似乎有一个缺点。使用 ItemsControl,我有一个 <Style TargetType="{x:Type ListBoxItem}"> XAML 部分,用于在鼠标悬停事件时控制单个列表框项目的边框、突出显示等。使用 ItemsControl,样式将应用于整个列表,而不仅仅是单个项目。我尝试使用<Style TargetType="{x:Type ItemsControlItem}"> 重写我的样式,但这不存在。选项?
  • 简单 ItemsControl 的项目被包装到 ContentPresenter 中。不幸的是,它没有 Template 属性。

标签: c# wpf listbox


【解决方案1】:

您可以像这样将 ListBoxItem.IsEnabled 属性设置为 false:

<ListBox x:Name="_sampleListBox">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsEnabled" Value="False"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

这将使项目无法被选中。不过它可能看起来有点有趣......你可以尝试使用这样的模板:

<ListBox x:Name="_sampleListBox">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsEnabled" Value="False"/>
            <Style.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Foreground" Value="Red" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

【讨论】:

  • 这不适合我的需要。请参阅我的问题陈述中的第二句。
  • 非常适合我的 :) +1
【解决方案2】:

您可以使用此 ListBox 禁用选择的视觉效果:

<Style x:Key="NoSelectionListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="Padding" Value="2,0,0,0"/>
    <Setter Property="FocusVisualStyle">
        <Setter.Value>
            <Style>
                <!-- This removes focus visualization -->
                <Setter Property="Control.Template" Value="{x:Null}"/>
            </Style>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                                            <!-- Some default triggers removed to avoid background changes on selection -->
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

也许更简洁的解决方案是创建您自己的 ItemsControl,其中包含可能具有其样式的特定项目容器。

【讨论】:

  • 我已经将这个 Style 块添加到我的 XAML 中,完全按照编写的方式进行编译和运行,但我的列表框项目的选择行为没有变化。
  • 您是否将其设置为 ListBox 的 ItemsContainerStyle?
猜你喜欢
  • 2018-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多