使WPF中的Listbox项目不可选择

68

我在WPF中有一个列表框,当用户选择一个项目时,会显示一些不好看的颜色。我能不能让所有项目都不可选呢?


3
订正事情永远不会太晚。 - Jony Adamit
在列表框上设置Enabled="false"。透明度可以通过CSS进行调整。 - Jujucat
11个回答

105
如果不需要选择,使用ItemsControl而不是ListBox

24
并非总是正确的;ItemsControl无法像ListBox那样完成一些可能需要的功能,比如在使用虚拟化时的ScrollIntoView - Seth Carnegie
4
不一定正确。可能有许多原因不想使用ListBox的原始选择机制,但仍保留功能:举一个例子,考虑一个图像列表框,您想在每个图像的角落添加一个额外的复选框以启用选择。您将连接此复选框到原始选择机制,但仍希望禁用ListBox的原始单击选择。 - Gábor

48
在ListBoxItem的样式中添加Focusable属性,值为false:
<Style x:Key="{x:Type ListBoxItem}" TargetType="{x:Type ListBoxItem}">
  <!-- Possibly other setters -->
  <Setter Property="Focusable" Value="False" />
</Style>

4
这是真正的答案。 - Gábor

25
请在您的列表框中使用此代码。我发现这是一个非常优雅的解决方案。
<ListBox ItemsSource="{Binding YourCollection}">
    <ListBox.ItemContainerStyle>
       <Style TargetType="{x:Type ListBoxItem}">
           <Setter Property="Focusable" Value="False"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

1
最优雅的解决方案。 - CCamilo

15

如果您不希望它们可选择,那么您可能不需要一个列表视图。 但如果这是您真正需要的,那么您可以使用样式来实现:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Page.Resources>


<Style x:Key="{x:Type ListBoxItem}" TargetType="{x:Type ListBoxItem}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type ListBoxItem}">
        <Border 
          Name="Border"
          Padding="2"
          SnapsToDevicePixels="true">
          <ContentPresenter />
        </Border>
        <ControlTemplate.Triggers>
          <Trigger Property="IsSelected" Value="true">
            <Setter TargetName="Border" Property="Background" Value="#DDDDDD"/>
          </Trigger>
          <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Foreground" Value="#888888"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

  </Page.Resources>
  <Grid>  
    <ListBox>
      <ListBoxItem>One</ListBoxItem>
      <ListBoxItem>Two</ListBoxItem>
      <ListBoxItem>Three</ListBoxItem>
    </ListBox>
  </Grid>
</Page>

看一下IsSelected触发器。你可以将边框设置为不同的颜色,这样它就不会显得"丑陋",或者将其设置为透明,在选择时就不会可见。

希望这能帮到你。


3
同时添加 <Setter Property="FocusVisualStyle" Value="{x:Null}" /> 以去除焦点矩形。 - Gábor

9
有一种更简单的方法:设置 ListBox 属性为 IsHitTestVisible="False"。这会阻止列表中所有项目接收鼠标事件。这样做的好处是,可以停止鼠标悬停时的高亮显示。
在 WP 7.1 中,此方法适用。

2
但是整个列表框都不响应了.. 包括滚动条。 - Elad Katz
1
@EladKatz:没错。这就是为什么我有时会在ListBox周围添加自己的ScrollViewer来重新建立滚动的原因。 - Denise Draper
@DeniseDraper 这是个好主意,但当列表满了时我的滚动视图无法“滚动”。我知道内容足够让滚动条工作,但它仍然保持“不活跃”状态。你有什么想法吗? - StinkyCat
@StinkyCat:这里没有任何想法,抱歉。在StackOverflow上,滚动时发生奇怪的事情是一个经常被提问的主题,所以我怀疑它与这种情况没有任何特定的联系。 - Denise Draper
到目前为止,呈现一个需要变得不可选择的项目列表框最简单和最直接的解决方案是。 - BoiseBaked
我来这里是为了解决嵌套列表视图的问题,这个解决方案对我来说最好用。(内部列表视图不能是ItemsControl,因为我在其他地方使用了一个UserControl,我需要它是可选择的)。 - Danwizard208

3

使用上面viky的答案,简单地实现这个功能的方法是在SelectionChanged()中将选定的索引设置为-1,如下所示。

public void OnListView_SelectionChanged(Object sender, RoutedEventArgs e)
{
    if (null != sender && sender is ListView)
    {
        ListView lv = sender as ListView;
        lv.SelectedIndex = -1;
    }
}

3
最好避免使用事件,使用样式标签更加优雅且没有副作用。
<ListBox>
  <ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
      <Setter Property="IsEnabled" Value="False"/>
    </Style>
  </ListBox.ItemContainerStyle>
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel>
        ... what you want as a source ...
       </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

1
您还可以制作禁用的列表框,这将为您提供静态的、非交互式的列表框。
<ListBox IsEnabled="False"/>

我认为这是尽可能简单的解决方案。

1
你可以处理 ListBox 的 SelectionChanged 事件,并在事件处理程序中取消选择选定的项。

0
在我的情况下,我使用了带有Textblock和ComboBox的模板化ListboxItems。唯一“活动”的应该是组合框...
<ScrollViewer VerticalScrollBarVisibility="Auto"
              HorizontalScrollBarVisibility="Disabled"
              CanContentScroll="True" />
    <ItemsControl>
     ....here my content....
    </Itemscontrol>
</ScrollViewer>

对我来说按预期工作了。 敬礼, 丹尼尔


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