В WPF ListView на событие SelectionChanged

у меня есть ListView привязка к ItemsSource. Почему SelectionChanged событие, запускающее события load/databound? Я предполагаю, что это потому, что выбраны элементы "по умолчанию", т. е. индекс 0.

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

спасибо Петрус!--4-->

5 ответов


listView не должен запускать SelectionChange, если задано только свойство ItemsSource. Однако при привязке свойства SelectedIndex к свойству объекта dataContext выделение будет перемещено в индекс, указанный свойством binded.

это не вызывает событие Selector_OnSelectionChanged при загрузке страницы:

<ListView SelectionChanged="Selector_OnSelectionChanged" 
                  ItemsSource="{Binding Path=Items}"
                  ></ListView>

а это:

<ListView SelectionChanged="Selector_OnSelectionChanged" 
                  SelectedIndex="{Binding Path=SelectedIndexValue}"
                  ItemsSource="{Binding Path=Items}"
                  ></ListView>

потому что SelectedIndex имеет значение SelecteIndexValue через обязательный.

чтобы избежать этого и сохранить привязки в разметке, установите SelectedIndexValue объекта dataContext в -1 перед привязкой (перед вызовом InitializeComponent() в конструкторе формы).

надеюсь, что это помогает.


спасибо за ответы.

когда я помещаю точку останова в событие SelectionChanged, он прерывает работу там до полной загрузки экрана. Вы также увидите, что первая строка "выбрана" после этого в списке. Я не привязан к SelectedIndexValue, как вы можете видеть в коде. DataContext для списка является ReadonlyCollection

в моем событии SelectionChanged, как вы можете видеть, я уведомляю другие объекты, которые будут загружены данными, относящимися к выбранный пункт. Я хочу, чтобы это произошло только тогда, когда один выбран, но не по умолчанию. Я должен из этих ListViews, представляющих аналогичные данные, но при загрузке ни один не должен иметь выбранного элемента.

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

<ListView PreviewMouseDown="ActiveCasesView_MouseDown" x:Name="ActiveCasesView"
                     DataContext="{StaticResource ActiveCasesViewSource}"
                     ItemsSource="{Binding}"
                     ItemTemplate="{StaticResource CasesItemTemplate}"
                     SelectionMode="Single"
                     SelectionChanged="ActiveCasesView_SelectionChanged"
                     ScrollViewer.CanContentScroll="True" 
                     ScrollViewer.VerticalScrollBarVisibility="Auto" >
</ListView>

private void ActiveCasesView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (mouseClicked)
            if (e.AddedItems.Count > 0)
                App.Messenger.NotifyColleagues(App.MSG_SELECT_ACTIVE_CASE, ((CaseViewModel)ActiveCasesView.SelectedItem).CaseNumber);
    }

Я добавил PreviewMouseDown для установки индикатор, который я нажал на listview в событии SelectionChanged. Это помогает, Но я не уверен, что это лучшее решение.

спасибо Петрус!--2-->


Я не знаю, нужна ли вам помощь в этом, но я решил эту проблему, сделав переменную, которая отслеживает selectedindex, в моем случае-когда изначально привязана, это всегда 0, поэтому мне немного легче сделать, однако, если вы сообщите viewmodel соответствующего индекса, я просто добавил

ComboBox box = e.OriginalSource as ComboBox;
if (_previousIndex == cb.SelectedIndex) return;
//do stuff you need to do with a new SelectedIndex

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

<ListView PreviewMouseDown="ActiveCasesView_MouseDown" x:Name="ActiveCasesView"
                     DataContext="{StaticResource ActiveCasesViewSource}"
                     ItemsSource="{Binding}"
                     ItemTemplate="{StaticResource CasesItemTemplate}"
                     SelectionMode="Single"
                     SelectionChanged="ActiveCasesView_SelectionChanged"
                     ScrollViewer.CanContentScroll="True" 
                     ScrollViewer.VerticalScrollBarVisibility="Auto" 
**SelectedIndex="-1"**>
</ListView>

Я попытался воспроизвести ваше поведение, но безуспешно. Каков тип коллекции ItemsSource, к которой вы привязываетесь?


вы можете использовать событие window loaded для блокировки действия

bool loaded = false;

window.Loaded += new RoutedEventHandler(MainWindow_Loaded);

void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
   windowLoaded = true;
}

private void ActiveCasesView_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{

if(!loaded)
return ;

//do actions here ....

}