В 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 ....
}