WPF Listview SelectionChanged event

2019-03-15 12:18发布

I have a ListView binding to an ItemsSource. Why is the SelectionChanged event firing on the load/databound events? I assume that it is because a 'default' items ie index 0 is selected.

How can I disable this, because when selecting an item updated other sources with data.

Thanks Petrus

5条回答
孤傲高冷的网名
2楼-- · 2019-03-15 12:48

you can use window loaded event to block the action

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

}
查看更多
我想做一个坏孩纸
3楼-- · 2019-03-15 12:50

The listView should not fire the SelectionChange if you only set the ItemsSource property. However if you bind the SelectedIndex property to a property of your dataContext object the selection will move to the index that is specified by the binded property.

this doesn't fires the Selector_OnSelectionChanged event when the page loads:

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

but this does:

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

because the SelectedIndex is set to the SelecteIndexValue through binding.

To avoid this and still keep the bindings in your markup set the SelectedIndexValue of your dataContext object to -1 before binding (Before InitializeComponent() is called in your form constructor).

Hope this helps.

查看更多
男人必须洒脱
4楼-- · 2019-03-15 12:54

I don't know if you still need help with this, but I solved this problem by making a variable that tracks the selectedindex, in my case -- when initially bound it's always 0 so it's a little easier for me to do, however if you inform the viewmodel of the appropriate index, I simply added a

ComboBox box = e.OriginalSource as ComboBox;
if (_previousIndex == cb.SelectedIndex) return;
//do stuff you need to do with a new SelectedIndex
查看更多
女痞
5楼-- · 2019-03-15 13:02

You can try to set the SelectedIndex property to -1 in your binding but this also is not an elegant solution.

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

I tried to reproduce your behavior but without success. What is the Type of the ItemsSource collection that you are binding to?

查看更多
做自己的国王
6楼-- · 2019-03-15 13:15

thanks for the responses.

When I put a breakpoint on the SelectionChanged event, it breaks proceedings there before the screen is fully loaded. You will also see that the first row is 'selected' afterwards on the list. I am not binding to a SelectedIndexValue as you can see in the code. The DataContext for the list is a ReadonlyCollection

In my SelectionChanged event as you can see I notify other objects to be loaded with data relating to the selected item. I only want this to happen when one is selected but not a default one to be set. I have to of these ListViews representing similar data but on loaded none must have an item selected.

I have noticed that the default Selected index is set to -1 on the properties window for the Listview. I can even set this is code on the List_Loaded event, but by then the first SelectionChanged has happened already.

<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);
    }

I added the PreviewMouseDown to set an indicator that I have clicked on the listview in the SelectionChanged event. This does help but I'm not convinced that its the best solution.

Thanks Petrus

查看更多
登录 后发表回答