首页 文章

没有ListBox.SelectionMode =“None”,还有另一种禁用列表框中选择的方法吗?

提问于
浏览
174

如何禁用ListBox中的选择?

16 回答

  • 248

    方法1 - ItemsControl

    除非您需要 ListBox 的其他方面,否则您可以使用 ItemsControl . 它将项目放在 ItemsPanel 中,并且没有选择的概念 .

    <ItemsControl ItemsSource="{Binding MyItems}" />
    

    默认情况下, ItemsControl 不支持其子元素的虚拟化 . 如果您有很多项目,虚拟化可以减少内存使用并提高性能,在这种情况下,您可以使用方法2并设置 ListBoxadd virtualisation to your ItemsControl样式 .

    方法2 - 样式ListBox

    或者,只需设置ListBox的样式,使选择不可见 .

    <ListBox.Resources>
      <Style TargetType="ListBoxItem">
        <Style.Resources>
          <!-- SelectedItem with focus -->
          <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
                           Color="Transparent" />
          <!-- SelectedItem without focus -->
          <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
                           Color="Transparent" />
          <!-- SelectedItem text foreground -->
          <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}"
                           Color="Black" />
        </Style.Resources>
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
      </Style>
    </ListBox.Resources>
    
  • 2

    我找到了一个非常简单直接的解决方案,我希望它能帮到你

    <ListBox ItemsSource="{Items}">
        <ListBox.ItemContainerStyle>
           <Style TargetType="{x:Type ListBoxItem}">
               <Setter Property="Focusable" Value="False"/>
           </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
    
  • 0

    您可以切换到使用 ItemsControl 而不是 ListBox . ItemsControl 没有选择的概念,所以没有什么可以关闭的 .

  • 143

    另一个值得考虑的选择是禁用ListBoxItems . 这可以通过设置ItemContainerStyle来完成,如下面的代码片段所示 .

    <ListBox ItemsSource="{Binding YourCollection}">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="IsEnabled" Value="False" />
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
    

    如果您不希望文本为灰色,则可以通过使用以下键向样式的资源添加画笔来指定禁用的颜色:{x:Static SystemColors.GrayTextBrushKey} . 另一种解决方案是覆盖ListBoxItem控件模板 .

  • 0

    这也可以,如果我需要使用listbox而不是itemscontrol,但我只是显示不应该选择的项目,我使用:

    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsHitTestVisible" Value="False" />
        </Style>
    </ListBox.ItemContainerStyle>
    
  • 6

    虽然@Drew Noakes的答案是大多数情况下的快速解决方案,但设置x:静态画笔会带来一些缺陷 .

    当您按照建议设置x:静态画笔时,列表框项目中的所有子控件都将继承此样式 .

    这意味着,虽然这将禁用列表框项的突出显示,但它可能会导致子控件的不良影响 .

    例如,如果您的ListBoxItem中有一个ComboBox,它将禁用鼠标而不是ComboBox中的突出显示 .

    相反,请考虑为此stackoverflow线程中提到的解决方案中包含的Selected,Unselected和MouseOver事件设置VisualStates:Remove Control Highlight From ListBoxItem but not children controls .

    -Frinny

  • 12

    Hallgeir Engen的答案是一个很好的解决方案,但问题是在回发后,所有项目都可以再次选择,因此它要求您在 Page_Load 中为每个ListItem添加disabled属性 .

    但是甚至有更简单的解决方案 .

    您可以这样做,而不是禁用所有ListItems禁用ListBox本身 once ,并且所有列表项也被禁用 . set Enabled为false, doesn't 禁用ListBox at all ,但在 Page_Load 中添加以下行:

    this.listbox.Attributes.Add("disabled", "disabled");
    

    回发后,项目 don't 变为可选项,因此您可以将此代码行放入:

    if (!this.IsPostBack)
    {
    }
    

    但是 all 项仍然是灰色叠加,所以如果要为 all 项着色,那么制作css类:

    .ListItemColor option
    {
        color: Black; /*(default color for list item, if it is not disabled)*/
    }
    

    然后将ListBox的CssClass设置为上面的css类 . 如果你想为列表项目(但不是全部)着色,那么你将需要设置一些项目的样式,并通过源(标记)或代码(javascript,c#或Visual Basic)为每个项目赋予颜色 .

  • 24

    这里的答案相当不错,但我正在寻找一些略有不同的东西:我想要选择,但只是不希望它被展示(或以不同的方式展示) .

    上面的解决方案对我来说不起作用(完全),所以我做了其他的事情:我为列表框使用了一种新样式,它完全重新定义了模板:

    <Style x:Key="PlainListBoxStyle" TargetType="ListBox">
        <Setter Property="ItemContainerStyle">
            <Setter.Value>
                <Style TargetType="ListBoxItem">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListBoxItem">
                                <ContentPresenter />
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBox}">
                    <ItemsPresenter/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    从那开始,您可以轻松地添加自己的选择突出显示,或者如果您根本不想要任何突出显示,则保留它 .

  • -3

    也许你需要ItemsControl的onlly功能?它不允许选择:

    <ItemsControl ItemsSource="{Binding Prop1}" ItemTemplate="{StaticResource DataItemsTemplate}" />
    
  • -3

    Note: This solution does not disable selection by keyboard navigation or right clicking (即箭头键后跟空格键)

    所有先前的答案要么删除能力选择completly(在运行时没有切换)或只是删除视觉效果,而不是选择 .

    但是,如果您希望能够通过代码选择和显示选择,而不是通过用户输入,该怎么办?可能是您想要“冻结”用户的选择而不禁用整个列表框?

    解决方案是将整个ItemsContentTemplate包装到没有可视化镶边的Button中 . 按钮的大小必须等于项目的大小,因此它完全被覆盖 . 现在使用按钮的IsEnabled-Property:

    启用按钮以“冻结”项目的选择状态 . 这是因为启用按钮在它们冒泡到ListboxItem-Eventhandler之前会占用所有鼠标事件 . 您的ItemsDataTemplate仍将接收MouseEvents,因为它是按钮内容的一部分 .

    禁用该按钮以通过单击更改选择 .

    <Style x:Key="LedCT" TargetType="{x:Type ListBoxItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Button IsEnabled="{Binding IsSelectable, Converter={StaticResource BoolOppositeConverter}}" Template="{DynamicResource InvisibleButton}">
                            <ContentPresenter />
                    </Button>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    <ControlTemplate x:Key="InvisibleButton" TargetType="{x:Type Button}">
        <ContentPresenter/>
    </ControlTemplate>
    

    dartrax

  • 0

    您可以在列表框上方放置一个Textblock,它不会改变应用程序的外观,也不会允许选择任何项目 .

  • 0

    例如,在Windows Phone上运行的简单修复是选择将所选项设置为null:

    <ListBox SelectionChanged="ListBox_SelectionChanged">
    

    并在代码背后:

    private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            (sender as ListBox).SelectedItem = null;
        }
    
  • 0

    对我来说最好的解决方案是

    <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Focusable" Value="True"/>
                    <Setter Property="IsHitTestVisible" Value="False" />
                </Style>
            </ListBox.ItemContainerStyle>
    
  • 2

    我找到了一个完美的方式 .
    将ListBox IsHitTestVisible设置为false,以便用户无法鼠标悬停或向下滚动或向上滚动 .
    Capture PreviewGotKeyboardFocus e.Handled = true,以便用户可以通过键盘选项卡,向上箭头,向下箭头选择项目 .

    这样的优势:

    • ListBox项目前景不会变为灰色 .

    • ListBox Background可以设置为Transparent

    Xmal位

    <ListBox Name="StudentsListBox" ItemsSource="{Binding Students}" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" BorderThickness="0" Background="Transparent" IsHitTestVisible="False" PreviewGotKeyboardFocus="StudentsListBox_PreviewGotKeyboardFocus">
    
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Padding" Value="0"/>
                <Setter Property="Margin" Value="0"/>
    
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Border x:Name="Bd">
                                <ContentPresenter/>
                            </Border>
                            <ControlTemplate.Triggers>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="Selector.IsSelectionActive" Value="False" />
                                        <Condition Property="IsSelected" Value="True" />
                                    </MultiTrigger.Conditions>
                                    <Setter TargetName="Bd" Property="Background" Value="Yellow" />
                                    <Setter TargetName="Bd" Property="BorderBrush" Value="Transparent" />
                                </MultiTrigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
    
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Margin="0,0,0,0">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0" Name="GradeBlock" Text="{Binding Grade}" FontSize="12" Margin="0,0,5,0"/>
                    <TextBlock Grid.Column="1" Name="NameTextBlock" Text="{Binding Name}" FontSize="12" TextWrapping="Wrap"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    
    </ListBox>
    

    private void StudentsListBox_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        e.Handled = true;
    }
    
  • 1

    IsEnabled = false

  • -3

    要禁用列表框/下拉列表中的一个或多个选项,您可以添加“已禁用”属性,如下所示 . 这会阻止用户选择此选项,并获得灰色叠加层 .

    ListItem item = new ListItem(yourvalue, yourkey);
    item.Attributes.Add("disabled","disabled");
    lb1.Items.Add(item);
    

相关问题