WPF Listview SelectionChanged событие
У меня есть привязка ListView
к ItemsSource
.
Почему событие SelectionChanged
срабатывает при событиях load/databound? Я предполагаю, что это происходит потому, что выбраны элементы по умолчанию, то есть индекс 0.
Как я могу отключить это, потому что при выборе элемента обновлялись другие источники с данными.
Спасибо
Petrus
Ответы
Ответ 1
спасибо за ответы.
Когда я помещаю точку останова на событие 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. Это помогает, но я не уверен, что это лучшее решение.
Спасибо
Petrus
Ответ 2
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() вызывается в вашем конструкторе форм).
Надеюсь, что это поможет.
Ответ 3
Я не знаю, нужна ли вам помощь в этом случае, но я решил эту проблему, создав переменную, которая отслеживает выбранный индекс, в моем случае - когда первоначально привязана всегда 0, поэтому мне немного легче сделать, однако, если вы сообщите viewmodel соответствующего индекса, я просто добавил
ComboBox box = e.OriginalSource as ComboBox;
if (_previousIndex == cb.SelectedIndex) return;
//do stuff you need to do with a new SelectedIndex
Ответ 4
Вы можете попробовать установить свойство 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, к которой вы привязываетесь?
Ответ 5
вы можете использовать событие, загруженное в окно, чтобы заблокировать действие
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 ....
}