WPF Listview SelectionChanged 事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1367665/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:56:45  来源:igfitidea点击:

WPF Listview SelectionChanged event

wpflistviewselectionchanged

提问by Petrus

I have a ListViewbinding to an ItemsSourceand the SelectionChangedevent is firing on the load/databound events? I assume that it is because a 'default' items ie index 0 is selected.

我有一个ListView绑定,ItemsSource并且SelectionChanged事件正在加载/数据绑定事件上触发?我认为这是因为选择了“默认”项目,即索引 0。

How can I disable this?

我怎样才能禁用它?

采纳答案by Petrus

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

当我在 SelectionChanged 事件上放置断点时,它会在屏幕完全加载之前中断那里的进程。您还将看到第一行随后在列表中被“选中”。正如您在代码中看到的那样,我没有绑定到 SelectedIndexValue。列表的 DataContext 是 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.

如您所见,在我的 SelectionChanged 事件中,我通知其他对象加载与所选项目相关的数据。我只希望在选择一个而不是默认设置时发生这种情况。我必须使用代表相似数据的这些 ListViews,但在加载时没有必须选择一个项目。

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.

我注意到默认的 Selected 索引在 Listview 的属性窗口中设置为 -1。我什至可以在 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);
    }

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.

我添加了 PreviewMouseDown 来设置一个指示器,我在 SelectionChanged 事件中单击了列表视图。这确实有帮助,但我不相信它是最好的解决方案。

Thanks Petrus

谢谢佩特鲁斯

回答by Claudiu Mihaila

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.

如果您只设置 ItemsSource 属性,则 listView 不应触发 SelectionChange。但是,如果将 SelectedIndex 属性绑定到 dataContext 对象的属性,则选择将移动到绑定属性指定的索引。

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

这不会在页面加载时触发 Selector_OnSelectionChanged 事件:

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

因为 SelectedIndex 通过绑定设置为 SelecteIndexValue。

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

为了避免这种情况并仍然保持标记中的绑定,在绑定之前将 dataContext 对象的 SelectedIndexValue 设置为 -1(在表单构造函数中调用 InitializeComponent() 之前)。

Hope this helps.

希望这可以帮助。

回答by Jay

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

我不知道你是否还需要这方面的帮助,但我通过创建一个跟踪 selectedindex 的变量解决了这个问题,在我的情况下 - 最初绑定时它总是 0 所以对我来说更容易做,但是如果你通知视图模型适当的索引,我只是添加了一个

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

回答by Claudiu Mihaila

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

您可以尝试在绑定中将 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>

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

我试图重现你的行为,但没有成功。您绑定到的 ItemsSource 集合的类型是什么?

回答by m6azeez

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

}