Нет ListBox.SelectionMode = "Нет", есть ли другой способ отключить выбор в списке?

Как отключить выбор в ListBox?

Ответ 1

Подход 1 - ItemsControl

Если вам не нужны другие аспекты ListBox, вы можете использовать ItemsControl. Он помещает элементы в ItemsPanel и не имеет понятия выбора.

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

По умолчанию ItemsControl не поддерживает виртуализацию своих дочерних элементов. Если у вас много элементов, виртуализация может уменьшить использование памяти и повысить производительность, и в этом случае вы можете использовать подход 2 и создать стиль ListBox или добавить виртуализацию в свой 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>

Ответ 3

Вы можете переключиться на использование ItemsControl вместо ListBox. ItemsControl не имеет понятия выбора, поэтому ничего не отключить.

Ответ 4

Другой вариант, заслуживающий рассмотрения, - отключить 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.

Ответ 5

Это также сработает, если мне нужно использовать listbox вместо itemscontrol, но я просто показываю элементы, которые не следует выбирать, я использую:

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

Ответ 6

В то время как ответ @Drew Noakes - быстрое решение для большинства случаев, есть недостаток, связанный с установкой кистей x: Static.

Когда вы устанавливаете кисти x: Static, как было предложено, все элементы управления детьми в элементе списка наследуют этот стиль.

Это означает, что, хотя это будет работать для отключения подсветки элемента списка, это может привести к нежелательным эффектам для дочерних элементов управления.

Например, если у вас есть ComboBox внутри вашего ListBoxItem, он отключит мышь над подсветкой в ​​ComboBox.

Вместо этого рассмотрите возможность установки VisualStates для выбранных, не выбранных и событий MouseOver, как описано в решении, упомянутом в этом потоке stackoverflow: Удалить элемент управления из списка ListBoxItem, но не дочерние элементы управления.

-Frinny

Ответ 7

Может быть, вам нужны только функции ItemsControl? Он не позволяет выбирать:

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

Ответ 8

Здесь очень хорошие ответы, но я искал что-то немного другое: я хочу выбирать, но просто не хочу, чтобы он показывался (или показывался в другом материале).

Вышеупомянутые решения не работали для меня (полностью), поэтому я сделал что-то еще: я использовал новый стиль для своего списка, который полностью переопределяет шаблоны:

<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>

Начиная с этого, вы можете легко добавить к себе выделение выделения или оставить его таким, если вы вообще не хотите.

Ответ 9

Примечание. Это решение не отключает выбор с помощью клавиатуры или правой кнопкой мыши (т.е. клавиши со стрелками, а затем пробел)

Все предыдущие ответы либо полностью удаляют возможность выбора (без переключения во время выполнения), либо просто удаляют визуальный эффект, но не выбор.

Но что, если вы хотите иметь возможность выбирать и показывать выбор по коду, но не по вводу пользователя? Может быть, вы хотите "заморозить" выбор пользователя, не отключая весь список?

Решение состоит в том, чтобы обернуть весь элемент ItemsContentTemplate в кнопку, которая не имеет визуального хром. Размер кнопки должен быть равен размеру предмета, поэтому он полностью покрыт. Теперь используйте кнопку IsEnabled-Property:

Включите кнопку, чтобы "заморозить" элемент "Выбор". Это работает, потому что включенная кнопка ест все события мыши, прежде чем они перейдут к элементу ListboxItem-Eventhandler. Ваш ItemDataTemplate по-прежнему будет получать 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

Ответ 10

Вы можете разместить текстовый блок над своим списком, он не изменит внешний вид вашего приложения, а также не позволит выбрать какой-либо элемент.

Ответ 11

Простое исправление, которое работает на Windows Phone, например, при выборе значения выбранного элемента в значение null:

    <ListBox SelectionChanged="ListBox_SelectionChanged">

И в коде позади:

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

Ответ 12

IsEnabled = false

Ответ 13

Чтобы отключить один или несколько параметров в вашем списке/выпадающем списке, вы можете добавить атрибут "disabled", как показано ниже. Это предотвращает выбор пользователем этой опции и получает серый накладной.

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

Ответ 14

Ответ на Hallgeir Engen - это хорошее решение, но проблема в том, что после отправки сообщения все элементы снова становятся доступными для выбора, поэтому вам требуется Page_Load добавить каждый атрибут Disabled ListItem.

Но есть еще более простое решение.

Вместо отключения всех списков ListItems вы можете просто отключить сам ListBox один раз, и все его элементы списка также отключены. set Enabled to false, не отключает ListBox вообще, но добавление следующей строки в Page_Load делает:

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

После отправки сообщения элементы не становятся доступными, поэтому вы можете поместить эту строку кода в:

if (!this.IsPostBack)
{
}

Но элементы все по-прежнему являются серыми наложениями, поэтому, если вы хотите покрасить элементы all, затем введите класс css:

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

Затем установите CssClass из ListBox в этот класс css выше. Если вы хотите раскрасить элементы some (но не все), вам нужно будет подстроить некоторые элементы и дать каждому свой цвет через источник (разметку) или код (javascript, С# или Visual Basic).