WPF ListBox可以设置为“只读”吗?

15

我们有一个场景,要显示一系列项目并指示哪个是“当前”项目(例如,用小箭头标记或更改背景颜色)。

ItemsControl 对于我们来说不好用,因为我们需要“SelectedItem”的上下文。但是,我们想通过编程的方式移动选定项,并且不允许用户更改它。

有没有简单的方法使 ListBox 不可交互?我们可以通过故意吞噬鼠标和键盘事件来模拟它,但是我是否错过了某些基本属性(例如将“IsEnabled”设置为 false 而不影响其视觉样式)来得到我们想要的结果?

或者......是否有另一个WPF控件既具有 ItemsControl 的 SelectedItem 属性,又符合我们的需求?

4个回答

19

一种选择是将 ListBoxItem.IsEnabled 设置为 false

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

这将确保项目不可选择,但可能无法按照您的喜好渲染。要解决此问题,您可以尝试使用触发器和/或模板进行调整。例如:

<ListBox x:Name="_listBox">
    <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>

你的ControlTemplate正在执行DataTemplate的工作。除了IsEnabled的Setter之外,你还需要的是 <Trigger Property="IsEnabled" Value="False"><Setter Property="Foreground" Value="{StaticResource fgbrush}" /></Trigger> - Joel B Fant
你也可以将项目设置为不进行点击测试(Setter Property="IsHitTestVisible" Value="False"),这样它们将像通常情况下一样呈现(而不是因为被禁用而变灰),滚动条仍将起作用。 - Néstor Sánchez A.

3

我曾经遇到过同样的问题。我解决了这个问题,通过让IsEnabled保持为true,并处理ListBox的PreviewMouseDown事件。在处理程序中,如果您不希望它被编辑,则将e.Handled设置为true。

    private void lstSMTs_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        e.Handled = !editRights;
    }

您仍然可以使用键盘更改选择。此外,滚动条将无法工作。 - Neil

3
神奇的咒语是:
<ListBox IsHitTestVisible="False">

不幸的是,这也会阻止任何滚动条的工作。

解决方法是将列表框放在一个滚动查看器中:

<ScrollViewer>
    <ListBox IsHitTestVisible="False">
    </ListBox>
</ScrollViewer>

1
目前这个答案比被采纳的那个更好。 - Sean O'Neil
1
@SeanO'Neil 是的,就在“按趋势排序答案”选项消失的时候。 (-:= - Mike Nakis
希望它会回来。 - Mike Nakis

1

你的ItemsControl/ListBox是否已经进行了数据绑定?

我在想,你可以将每个项的背景Brush绑定到源数据的属性上,或者通过转换器传递该属性。类似于:

  <ItemsControl DataContext="{Binding Source={StaticResource Things}}" ItemsSource="{Binding}" Margin="0">
    <ItemsControl.Resources>
      <local:SelectedConverter x:Key="conv"/>
    </ItemsControl.Resources>
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <local:Control Background="{Binding Path=IsSelected, Converter={StaticResource conv}}"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

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