UWP ListBox点击后对话框重复弹出,为何触发两次事件?
解决UWP ListBox SelectionChanged事件重复触发对话框的问题
嘿,这个问题我做UWP项目时也踩过同款坑!根源在于你在对话框回调里操作了ListBox的Items集合,导致SelectionChanged事件被二次触发了。
问题原因分析
当你选中ListBox项触发SelectedIndexChanged后,在对话框的回调里执行myList.Items.RemoveAt(itemIndex)时:
- 移除选中项会导致ListBox的选中状态发生变化(SelectedIndex变为-1)
- 这个状态变化又会再次触发
SelectionChanged事件,于是对话框就被调用了两次
解决方案:临时取消事件订阅
在事件处理方法的开头,先取消SelectionChanged的事件订阅,等所有逻辑处理完成后再重新订阅,就能避免二次触发。另外,在点击Cancel时记得清除选中状态,避免后续交互异常。
修改后的代码如下:
private async void SelectedIndexChanged(object sender, SelectionChangedEventArgs e) { // 先取消事件订阅,防止二次触发 myList.SelectionChanged -= SelectedIndexChanged; int itemIndex = myList.SelectedIndex; // 提前判断索引是否有效,避免异常 if (itemIndex < 0) { myList.SelectionChanged += SelectedIndexChanged; return; } var messageDialog = new MessageDialog("What do you want to do?", "Alert!"); messageDialog.Commands.Add(new UICommand("Do It", null)); messageDialog.Commands.Add(new UICommand("Don't do it", null)); messageDialog.Commands.Add(new UICommand("Cancel", null)); var cmdClick = await messageDialog.ShowAsync(); Debug.WriteLine(itemIndex); if (cmdClick.Label == "Do It") { Debug.WriteLine("Do It"); myList.Items.RemoveAt(itemIndex); } else if (cmdClick.Label == "Don't do it") { Debug.WriteLine("No defect"); myList.Items.RemoveAt(itemIndex); } else if (cmdClick.Label == "Cancel") { Debug.WriteLine("Cancel"); // 清除选中状态,避免后续选中异常 myList.SelectedIndex = -1; } // 处理完成后重新订阅事件 myList.SelectionChanged += SelectedIndexChanged; }
另一种方案:用布尔标记控制
你也可以用一个类级别的布尔变量来标记是否正在处理事件,同样能避免重复触发:
private bool isProcessingDialog = false; private async void SelectedIndexChanged(object sender, SelectionChangedEventArgs e) { if (isProcessingDialog) return; isProcessingDialog = true; int itemIndex = myList.SelectedIndex; if (itemIndex < 0) { isProcessingDialog = false; return; } // 对话框逻辑和之前一致... isProcessingDialog = false; }
两种方法都能解决问题,看你个人习惯选择就行~
内容的提问来源于stack exchange,提问作者alexmark
相关产品推荐
相关产品推荐

