【问题标题】:C# Form Application - Modal Dialogs Have Wrong ParentC# 表单应用程序 - 模态对话框的父级错误
【发布时间】:2010-10-15 17:34:54
【问题描述】:

我有一个应用程序,它内置了一个异步操作,它循环大量项目并对每个项目执行冗长的计算,因为发生这种情况时,某些情况会导致应用程序弹出一个模式对话框供用户输入。有趣的是,我今天在运行此程序时注意到,在一个应用程序实例中,模态对话框不知何故得到了错误的父窗体——而不是为我的应用程序提供模态块,对话框将 Digsby 聊天窗口作为其父窗体。

它们成为子级的 Digsby 窗口大约在创建第一个对话框的同时(可能是完全相同的时间)弹出,并且看起来它们以某种方式相互交叉,因为 Digsby 窗口完全被阻塞,直到异步操作完成。考虑到每个进程线程的工作原理,我不知道这怎么可能,但它确实发生了。什么会导致这样的错误?顺便说一下,该应用程序是 C# .NET 3.5,带有在 Windows XP 上运行的 Windows 窗体。

简而言之,异步代码如下:

Action<List<ClubListing>> a = delegate(List<ClubListing> list)
        {
            for (int i = 0; i < list.Count; i++)
            {
                var cl = list[i];
                if (cl.MatchingClubListing == null)
                {
                    var compare = CompareNames(cl.Club.Name);
                    if (compare.Any(c => c.Value == 0 && c.Key.Club.State == cl.Club.State))
                    {
                        var match = compare.First(c => c.Value == 0 && c.Key.Club.State == cl.Club.State);
                        compareDialog.ClubA = cl.Club;
                        compareDialog.ClubB = match.Key.Club;
                        DialogResult dr = compareDialog.ShowDialog();
                        if (dr == DialogResult.Yes)
                        {
                            cl.MatchingClubListing = match.Key;
                            match.Key.MatchingClubListing = cl;
                        }
                        else if (dr == DialogResult.Abort)
                        {
                            break;
                        }
                    }
                }
                this.Invoke(new MethodInvoker(delegate()
                {
                    this.prbOperationProgress.Value = i;
                }));
            }
        };

        AsyncCallback callback = new AsyncCallback(SaveAndUpdate);
        var result = a.BeginInvoke(this.lbxLiveClubs.Items.Cast<ClubListing>().ToList(), callback, null);

【问题讨论】:

    标签: c# multithreading winforms windows-xp


    【解决方案1】:

    将父对话框作为参数添加到 compareDialog.ShowDialog()。例如:

    Form parent = ...;
    compareDialog.ShowDialog(parent);
    

    【讨论】:

    • 这是答案的原因是无参数 ShowDialog() 的文档说:“...当前活动的窗口是对话框的所有者。如果你想指定特定所有者,请使用此方法的其他版本。”见msdn.microsoft.com/en-us/library/c7ykbedk.aspx
    【解决方案2】:

    正如您调用ProgressBar 更新一样,您需要Invoke() 显示您的对话框。

    【讨论】:

      【解决方案3】:

      看起来您正在工作线程中显示比较对话框。我认为如果您使用对 Invoke 的调用来显示您的对话框,您可能会没事。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-05
        • 1970-01-01
        相关资源
        最近更新 更多