Как убедиться, что ни один элемент не выбран в ListBox привязки данных?

Хорошо, это должен быть повторяющийся вопрос, но я не могу найти ответ: у меня есть список, привязанный к коллекции. По умолчанию выбрано Items [0]. Как я могу предотвратить это, чтобы событие SelectionChanged возникало каждый раз, когда я нажимаю ListBoxItem?

РЕДАКТИРОВАТЬ: я уже отклонил маршрут SelectedIndex = -1, но я попытался снова: установка SelectedIndex на -1 в конструкторе Listbox (или в качестве атрибута в XAML) не работает. Кажется, что список заполняется после инициализации, и selectedindex в конце концов станет равным 0. Та же история для установки SelectedItem в null;

Я пробовал это:

<ListBox ItemsSource="{Binding Value}" 
         SelectionChanged="ListBox_SelectionChanged"
         IsSynchronizedWithCurrentItem="True"
         Loaded="ListBox_Loaded">
</ListBox>

с участием:

 private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if(e.AddedItems.Count==0)return;//Prevents stackoverflow! ;-)
        ((ListBox)e.OriginalSource).SelectedItem=null;
    }

private void ListBox_Loaded(object sender, RoutedEventArgs e)
{
    ((ListBox) sender).SelectedItem = null;
}

Это работает, НО вставляет пустую строку поверх элементов, отображаемых в списке, что очень некрасиво .... В моем конкретном случае я мог бы решить проблему, удалив атрибут IsSynchronizedWithCurrentItem.

Но я могу придумать множество сценариев, в которых это было бы неприемлемо.

Вышеупомянутое утверждение не имеет смысла: либо вы хотите использовать привязку master-detail и установить для IsSynchronizedWithCurrentItem значение true, либо вы этого не сделаете. Маловероятно, что вы захотите использовать привязку "главный-подробный", и тогда в вашем списке все время не будет выбранного в данный момент элемента.


person Dabblernl    schedule 24.11.2009    source источник


Ответы (7)


Используйте CollectionView как ItemsSource для вашего списка. Новый проект WPF без изначально выбранного элемента:

XAML:

<Window x:Class="ListBoxDataBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
    <ListBox 
        ItemsSource="{Binding Path=Value, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" 
        SelectionChanged="ListBox_SelectionChanged"
        IsSynchronizedWithCurrentItem="True"
        >
    </ListBox>
</Grid>
</Window>

cs:

public partial class Window1: Window {
    public IEnumerable Value {
        get { return (IEnumerable)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(IEnumerable), typeof(Window1), new UIPropertyMetadata(null));


    public Window1() {
        InitializeComponent();
        var view = new TheCollectionView();
        view.MoveCurrentTo(null);
        this.Value = view;
    }

    private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
        MessageBox.Show("Selection changed");
    }
}

public class TheCollectionView: CollectionView {
    public TheCollectionView(): base(new TheCollection()) {
    }
}

public class TheCollection: List<string> {
    public TheCollection() {
        Add("string1");
        Add("string2");
        Add("string3");
    }
}
person Stanislav Kniazev    schedule 29.11.2009
comment
Очень хорошо, в коде показаны некоторые подходы, с которыми я тоже не был знаком. Спасибо! - person Dabblernl; 29.11.2009
comment
Извините за код - это просто быстрый и грязный способ продемонстрировать решение. Сам код ошибочен во многих аспектах. - person Stanislav Kniazev; 30.11.2009

После выполнения нескольких тестов поведение ListBox по умолчанию - не выбирать элемент в списке заранее. Удаление IsSynchronizedWithCurrentItem = "True" гарантирует, что список не запускается предварительно выбранным, и событие SelectionChanged будет возникать, когда пользователь щелкает любой элемент.

Если вы установите для IsSynchronizedWithCurrentItem значение true, это означает, что selectedIndex всегда будет равен индексу ListBox.Items.CurrentItem для ListBox.Items. ListBox.Items всегда имеет CurrentItem и не может иметь значение -1 или null, поскольку CurrentItem или CurrentIndex доступны только для чтения.

Надеюсь, это поможет Дж.

изменить ... только что прочитал

«В моем конкретном случае я мог бы решить проблему, удалив атрибут IsSynchronizedWithCurrentItem. Но я могу придумать множество сценариев, в которых это было бы неприемлемо».

В этом случае я не думаю, что это возможно по причинам, указанным выше.

person James Hay    schedule 29.11.2009
comment
Спасибо, по крайней мере, это объясняет причину проблемы! - person Dabblernl; 29.11.2009
comment
Спасибо! Понимание этого было для меня ключевым моментом в решении этой проблемы в нашем приложении. - person CuriousKea; 25.09.2013

listbox.selectedIndex = -1

Это должно отменить выбор всего (поскольку индекс -1 не существует), но, насколько мне известно, если вы явно не установили selectedItem по умолчанию, список создается без выбора, поэтому возможно, что SelectedIndex был случайно установлен на какой-то момент. Обратите внимание, что SelectedIndex также может быть установлен в XAML.

person MoominTroll    schedule 24.11.2009

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

Надеюсь, это поможет, С уважением, Том.

person t0mm13b    schedule 24.11.2009

Как насчет сброса обработчика событий SelectionChanged и привязки данных свойства зависимости или свойства уведомления к SelectedValue?

person Danny Varod    schedule 27.11.2009
comment
Что ж, это было интересное упражнение, но оно не меняет принципиального поведения. Более того, установка для SelectedValue значения null в PropertyChangedCallBack модели просмотра больше не работает, кажется, что выбранный элемент все равно выбран. - person Dabblernl; 28.11.2009

Просто зайдите в свойства списка. Выберите вкладку «Данные», а затем выберите «Связанный столбец». Введите -1. ​​Этот ввод автоматически изменится на 65535.

Затем измените свойство «Разрешить редактирование списка значений» на «Нет». Наконец, измените свойство «Заблокировано» на «Нет».

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

person Texas    schedule 14.07.2020

Вы можете использовать событие Tap вместо SelectionChanged:

<ListBox  ItemsSource="{Binding Data}" Tap="ListBox_Tap" ... />
person Oscar Fraxedas    schedule 20.06.2013