是否可以在不阻止所有表单的情况下使用 ShowDialog?

2023-11-24

我希望我能足够清楚地解释这一点。我有我的主表单 (A),它使用 form.Show() 打开 1 个子表单 (B),使用 form.Show() 打开第二个子表单 (C)。现在我希望子表单 B 使用 form.ShowDialog() 打开表单 (D)。当我这样做时,它也会阻止 A 型和 C 型。有没有办法打开模式对话框并仅阻止打开它的表单?


使用多个 GUI 线程是一件棘手的事情,如果这是您这样做的唯一动机,我建议您不要这样做。

更合适的方法是使用Show()代替ShowDialog(),并禁用所有者表单,直到弹出表单返回。无外乎四点考虑:

  1. When ShowDialog(owner)使用时,弹出窗体保留在其所有者的顶部。当你使用时也是如此Show(owner)。或者,您可以设置Owner明确属性,具有相同的效果。

  2. 如果您设置所有者表单的Enabled财产给false,窗体显示禁用状态(子控件“变灰”),而当ShowDialog使用时,所有者表单仍然被禁用,但不显示禁用状态。

    你打电话时ShowDialog,所有者窗体在 Win32 代码中被禁用 - 它WS_DISABLED样式位已设置。这会导致它失去获得焦点的能力并在单击时发出“叮”声,但不会使其自身绘制为灰色。

    当您设置表单的Enabled财产给false,设置了一个附加标志(在框架中,而不是底层 Win32 子系统),某些控件在绘制自身时会检查该标志。该标志告诉控件将自己绘制为禁用状态。

    所以要模拟会发生什么ShowDialog,我们应该设置本机WS_DISABLED直接样式位,而不是设置表单的Enabled财产给false。这是通过一点点互操作来完成的:

    const int GWL_STYLE   = -16;
    const int WS_DISABLED = 0x08000000;
    
    [DllImport("user32.dll")]
    static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    
    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    
    void SetNativeEnabled(bool enabled){
        SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE) &
            ~WS_DISABLED | (enabled ? 0 : WS_DISABLED));
    }
    
  3. The ShowDialog()在对话框关闭之前,调用不会返回。这很方便,因为您可以暂停所有者表单中的逻辑,直到对话框完成其任务。这Show()call 必然不会有这样的行为。因此,如果您要使用Show()代替ShowDialog(),您需要将逻辑分为两部分。对话框关闭后应运行的代码(其中包括重新启用所有者表单)应由Closed事件处理程序。

  4. 当表单显示为对话框时,设置其DialogResult属性会自动关闭它。每当按钮带有DialogResult财产以外的财产None被点击。显示的表格Show不会像这样自动关闭,因此我们必须在单击其关闭按钮之一时显式关闭它。但请注意,DialogResult属性仍然可以通过按钮进行适当设置。

实现这四件事,你的代码会变成这样:

class FormB : Form{
    void Foo(){
        SetNativeEnabled(false); // defined above
        FormD f = new FormD();
        f.Closed += (s, e)=>{
            switch(f.DialogResult){
            case DialogResult.OK:
                // Do OK logic
                break;
            case DialogResult.Cancel:
                // Do Cancel logic
                break;
            }
            SetNativeEnabled(true);
        };
        f.Show(this);
        // function Foo returns now, as soon as FormD is shown
    }
}

class FormD : Form{
    public FormD(){
        Button btnOK       = new Button();
        btnOK.DialogResult = DialogResult.OK;
        btnOK.Text         = "OK";
        btnOK.Click       += (s, e)=>Close();
        btnOK.Parent       = this;

        Button btnCancel       = new Button();
        btnCancel.DialogResult = DialogResult.Cancel;
        btnCancel.Text         = "Cancel";
        btnCancel.Click       += (s, e)=>Close();
        btnCancel.Parent       = this;

        AcceptButton = btnOK;
        CancelButton = btnCancel;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以在不阻止所有表单的情况下使用 ShowDialog? 的相关文章

  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 如何在多线程C++ 17程序中交换两个指针?

    我有两个指针 pA 和 pB 它们指向两个大的哈希映射对象 当pB指向的哈希图完全更新后 我想交换pB和pA 在C 17中 如何快速且线程安全地交换它们 原子 我是 c 17 的新手 2个指针的原子无等待交换可以通过以下方式实现 inclu
  • 以编程方式读取 SQL Server 查询计划建议的 SQL 特定执行的索引?

    如果我在 SSMS 中运行此命令 set showplan xml on GO exec some procedure arg1 arg2 arg3 GO set showplan xml off GO 我获得查询执行中涉及的完整调用堆栈的
  • 在c#中执行Redis控制台命令

    我需要从 Redis 控制台获取 客户端列表 输出以在我的 C 应用程序中使用 有没有办法使用 ConnectionMultiplexer 执行该命令 或者是否有内置方法可以查找该信息 CLIENT LIST是 服务器 命令 而不是 数据库
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • 查找进程的完整路径

    我已经编写了 C 控制台应用程序 当我启动应用程序时 不使用cmd 我可以看到它列在任务管理器的进程列表中 现在我需要编写另一个应用程序 在其中我需要查找以前的应用程序是否正在运行 我知道应用程序名称和路径 所以我已将管理对象搜索器查询写入
  • 查看 NuGet 包依赖关系层次结构

    有没有一种方法 文本或图形 来查看 NuGet 包之间的依赖关系层次结构 如果您使用的是新的 csproj 您可以在此处获取所有依赖项 在项目构建后 项目目录 obj project assets json
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 将 Long 转换为 DateTime 从 C# 日期到 Java 日期

    我一直尝试用Java读取二进制文件 而二进制文件是用C 编写的 其中一些数据包含日期时间数据 当 DateTime 数据写入文件 以二进制形式 时 它使用DateTime ToBinary on C 为了读取 DateTime 数据 它将首
  • C# 存档中的文件列表

    我正在创建一个 FileFinder 类 您可以在其中进行如下搜索 var fileFinder new FileFinder new string C MyFolder1 C MyFolder2 new string
  • 启动时的 Excel 加载项

    我正在使用 Visual C 创建 Microsoft Excel 的加载项 当我第一次创建解决方案时 它包含一个名为 ThisAddIn Startup 的函数 我在这个函数中添加了以下代码 private void ThisAddIn
  • 如何在 C 中安全地声明 16 位字符串文字?

    我知道已经有一个标准方法 前缀为L wchar t test literal L Test 问题是wchar t不保证是16位 但是对于我的项目 我需要16位wchar t 我还想避免通过的要求 fshort wchar 那么 C 不是 C
  • 为什么我的单选按钮不起作用?

    我正在 Visual C 2005 中开发 MFC 对话框应用程序 我的单选按钮是 m Small m Medium 和 m Large 它们都没有在我的 m Summary 编辑框中显示应有的内容 可能出什么问题了 这是我的代码 Pizz
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • 使 Guid 属性成为线程安全的

    我的一个类有一个 Guid 类型的属性 该属性可以由多个线程同时读写 我的印象是对 Guid 的读取和写入不是原子的 因此我应该锁定它们 我选择这样做 public Guid TestKey get lock testKeyLock ret
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • 将数组作为参数传递

    如果我们修改作为方法内参数传递的数组的内容 则修改是在参数的副本而不是原始参数上完成的 因此结果不可见 当我们调用具有引用类型参数的方法时 会发生什么过程 这是我想问的代码示例 using System namespace Value Re
  • 使用 C 在 OS X 中获取其他进程的 argv

    我想获得其他进程的argv 例如ps 我使用的是在 Intel 或 PowerPC 上运行的 Mac OS X 10 4 11 首先 我阅读了 ps 和 man kvm 的代码 然后编写了一些 C 代码 include
  • 灵气序列解析问题

    我在使用 Spirit Qi 2 4 编写解析器时遇到一些问题 我有一系列键值对以以下格式解析
  • 不区分大小写的字符串比较 C++ [重复]

    这个问题在这里已经有答案了 我知道有一些方法可以进行忽略大小写的比较 其中涉及遍历字符串或一个good one https stackoverflow com questions 11635 case insensitive string

随机推荐

  • 容器的宽度不围绕 width:auto

    正如标题所述 如果我换行
  • console.log() 异步还是同步?

    我目前正在阅读异步 JavaScript作者 特雷弗 伯纳姆 到目前为止 这是一本很棒的书 他谈到此代码片段和 console log 在 Safari 和 Chrome 控制台中是 异步 的 不幸的是我无法复制这个 这是代码 var ob
  • Javascript 字符串 - 获取某个点的字符

    我有一个变量 var text hello 我想获得 0 位置的字符 所以 var firstChar text 0 简单的 在 Firefox 和 Chrome 中这是有效的 但在 IE 中我总是返回 未定义 有什么想法为什么会在 IE
  • Python、Pandas 和卡方独立性测试

    我对 Python 和统计都很陌生 我正在尝试应用卡方检验来确定以前的成功是否会影响一个人的变化水平 从百分比来看 情况似乎确实如此 但我想看看我的结果是否具有统计显着性 我的问题是 我这样做正确吗 我的结果显示 p 值为 0 0 这意味着
  • 警告:不建议在严格模式下使用 UNSAFE_componentWillMount(升级到 CRA 4.0.2)

    我将 React 应用程序从 16 3 更新到 React 17 同时升级到 电子邮件受保护 一切都按预期进行 但我在控制台中看到以下内容 Warning Using UNSAFE componentWillMount in strict
  • PHP:将多维数组转换为一维数组

    基本上 我的应用程序正在与一个 Web 服务进行交互 该服务会发回一个奇怪的多维数组 例如 Array 0 gt Array Price gt 1 1 gt Array Size gt 7 2 gt Array Type gt 2 这不是问
  • GNU 并行 --jobs 选项在集群上使用多个节点,每个节点有多个 cpu

    我正在使用 gnu Parallel 在每个节点有 2 个 CPU 的高性能 HPC 计算集群上启动代码 该集群使用 TORQUE 便携式批处理系统 PBS 我的问题是澄清 GNU 并行的 jobs 选项在这种情况下如何工作 当我运行不带
  • WPF 用户控件和名称范围

    我一直在使用 WPF 和 MVVM 并注意到一件奇怪的事情 使用时 Binding ElementName 在自定义用户控件上 用户控件内的根元素的名称似乎在使用该控件的窗口中可见 比如说 这是一个用户控件示例
  • 一条边转向零的最短路径

    给定一个无向加权图 G 和两个顶点 起始顶点和结束顶点 什么是最有效的算法 可以找到从开始到结束的最短路径 并且能够将一条边的权重变成零 编辑 我知道 dijkstra 算法 但正如我所说 这个问题的情况有所不同 我们可以将一个边缘转为零
  • 让 Vim 将所有空格显示为一个字符

    我找不到一种方法让 Vim 将所有空格显示为一个字符 我发现的只是制表符 尾随空格等 正如其他人所说 你可以使用 set list 这将与 set listchars 显示不可见字符 现在 没有一个明确的选项可以用来show空格 但在列表字
  • 如何在 Kotlin 中编写包级静态初始化器?

    之前的一个问题展示如何使用其静态初始化器将静态初始化器放入类中companion object 我试图找到一种在包级别添加静态初始值设定项的方法 但包似乎没有伴随对象 compiler error Modifier companion is
  • “使用未定义类型”与 unique_ptr 转发声明的类和默认的移动构造函数/赋值

    在下面的代码中 是避免编译错误并在 A cpp 中手动包含 B h 实现移动构造函数 赋值的唯一方法吗 A h include
  • 通知与 API 26 兼容

    我没有看到任何有关如何将 NotificationCompat 与 Android O 一起使用的信息Notification Channels 我确实看到一个新的构造函数需要channelId但如何获取 Compat 通知并在 Notif
  • 创建多行表头

    我有一个表格 其中的列标题是使用以下说明设置的 table setColumnHeader 我想知道如何创建多级表头 例如在本页 从 Vaadin 6 7 3 开始 使用库存 Vaadin 表组件目前无法实现此目的 在 Vaadin 7 中
  • 为什么我无法在 python 中创建轮子?

    以下是我正在运行的命令 python setup py bdist wheel usage setup py global opts cmd1 cmd1 opts cmd2 cmd2 opts or setup py help cmd1 c
  • JavaScript 中数组的三个等号返回 false。为什么?

    我知道 通常称为身份运算符 被比较的值必须具有相同的类型和值才能被视为相等 那么为什么下面的行返回 false 呢 Array asdf Array asdf 它们不相等 因为在每个语句中都创建了一个新数组 每个数组都是一个具有相同内容的全
  • 质因数分解 - 列表

    我正在尝试实现一个功能primeFac 以正整数作为输入n并返回一个列表 其中包含质因数分解中的所有数字n 我已经到目前为止 但我认为在这里使用递归会更好 不知道如何在这里创建递归代码 基本情况是什么 首先 My code def prim
  • 如何在 PHP 中将 12 小时制时间转换为 24 小时制时间?

    我正在使用以下函数 我想要 24 小时时钟格式的时间 但这给了我 12 小时的时间 我究竟做错了什么 来自文档用于date The H格式字符给出 24 小时格式的小时 另外 您可以使用G如果你不想领先0中午之前几个小时 Examples
  • 在java中旋转图像

    我有一张平移卡的图像 当我尝试将其旋转 45 度并保存时 我得到了一张裁剪后的图像 旋转图像的代码是 BufferedImage dimg new BufferedImage w h img getType Graphics2D g dim
  • 是否可以在不阻止所有表单的情况下使用 ShowDialog?

    我希望我能足够清楚地解释这一点 我有我的主表单 A 它使用 form Show 打开 1 个子表单 B 使用 form Show 打开第二个子表单 C 现在我希望子表单 B 使用 form ShowDialog 打开表单 D 当我这样做时