You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:04:32