• [WPF Bug清单]之(5)——隐藏模态对话框后变成非模态


    发现这个问题时,隐约记得之前有人已经发过这个问题,想把链接放到这里,不过找了半天,实在找不到。日后如果找到了一定加上。

    问题描述:ShowDialog方法弹出一个模态对话框,然后将此对话框的Visibility属性设置为Hidden,再设置回Visible,发现这个对话框已经不是模态的了。

    有人会觉得关就关了得了,也不会有这个问题,干什么要把Close取消掉然后再显示出来呢?因为这是有应用环境的。

    应用环境:有些对话框,从逻辑上就是单例的,比如OfficeVisual Studio里都有的查找对话框,显然没有必要同时显示两个。而且也没有必要每次重新实例化并显示出来,在用户关闭窗体时,将窗体隐藏起来会更好,这样上次查找的关键字还存在着。可以省去一些代码保存这个历史关键字。

    当然,这种方式也会有不好的地方,欢迎大家指摘。

    写了一个程序来模拟这个Bug,效果如下面三张图所示。

    1. 主窗体,点第一个按钮

     

    2. 弹出的模态对话框,点击按钮将自己隐藏

     

    3. 再点击主窗体的最后一个按钮,显示出来,已经是非模态对话框了

    以前发Bug,一般没有去看过.NET的源代码,这次感觉这个Bug 有点儿太不应该了,就看了看源代码,发现WPF还特意为Dialog(模态的)Hidden做了单独的处理,感觉就更不应该有问题了,我们来看看源代码。

    DoDialogHide

    其中直接把_showingAsDialog设置为了false,当再次把窗体的Visibility设置为Visible的时候,Window类又会根据这个变量的值来判断是否将窗体按模态的方式显示出来。而MS对这行代码的的注释仅仅是“// clears _showingAsDialog”。

    从源代码上来看,WPFWindow似乎是使用下面的代码将一个窗体从非模态变成模态的。

    SetAsModal

    但是当我自己在使用里使用这个方法的时候,却发现根本达不到目的。后来突然想到一个方法,试了一下,就可以。解决方法是,不使用Visibility = Visible,使窗体再次显示出来。而且再调用一次ShowDialog方法来显示这个窗体。这个方法也许只有对WPF不熟悉或是非常熟悉的人才能想得出来(我是死马当作活马医碰对了),因为正常情况下,继续地第二次调用ShowDialog方法是会抛出异常的。类似的诡异的Window的异常在[WPF]如何在关闭非模态子窗体时用消息框确认——解决最小化窗体时抛出的异常里也有描述。

    另外,在非UI线程弹出的MessageBox也是非模态的。这个解决方法很简单,只要在Dispatcher里弹出这个MessageBox就可以了。

    更多关于WPF Bug 

    同系列的其它文章:

    [WPF Bug清单]()与之(1)——可以多选的单选ListBox

    [WPF Bug清单](2)——RadioButtonIsChecked绑定失效

    [WPF Bug清单](3)——暗中创建文件的打开文件对话框

    [WPF Bug清单](4)——点击RadioButton的空白没有反应

    [WPF Bug清单](6)——ButtonIsCancel属性失效

    [WPF Bug清单](7)——顽固的Error Template

    [WPF Bug清单](8)——RowDefinitionMaxHeight在一定条件下失效

    [WPF Bug清单](9)——消失的光标

  • 相关阅读:
    获取表信息(MSSQL)
    合并有数据的列
    isnull的使用方法
    查询SQLServer的启动时间
    查询数据库中有数据的表
    查询数据库中表使用的空间信息。
    SQL Server SA 密码丢失无法连接数据库怎么办?
    tensorflow 语法及 api 使用细节
    Python: PS 滤镜-- Fish lens
    中英文对照 —— 概念的图解
  • 原文地址:https://www.cnblogs.com/nankezhishi/p/WPFBug5.html
Copyright © 2020-2023  润新知