65.9K
CodeProject 正在变化。 阅读更多。
Home

轻松添加“不再显示此对话框”复选框

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.95/5 (15投票s)

2007年7月21日

CPOL

4分钟阅读

viewsIcon

51530

downloadIcon

401

一个让用户选择不再显示对话框的控件。

SampleDialog.png

引言

当您需要向应用程序用户提出问题时,通常会显示一个对话框,用户可以通过单击按钮来回答您的问题。如果这个问题出现的频率很低,您可能可以跳过本文。但是,如果问题出现的频率很高,并且答案始终相同,用户在第 n 次(n >= 2 且因用户而异)关闭同一个对话框后会感到厌烦。这时,就该为对话框添加一个功能,允许用户将来跳过该对话框了。

本文介绍了一个可以为对话框添加此功能的控件。

背景

本文的理念是创建一个控件,尽可能简化“不再显示此对话框”的整个过程,以便使用该控件的开发人员能够快速添加控件,而无需进行大量配置。

如何着手解决问题

有两种可能的位置来解决这个问题:一是在实例化对话框并实际显示对话框(如果用户之前已单击“不再显示...”则不显示)的地方;二是在对话框本身内部,通过一个小技巧(稍后详述)。

我选择了第二种方案,因为这样一来,对话框的调用者就无需关心对话框是否具有“不再显示...”功能。创建和显示对话框的方式完全相同,无需进行任何更改。

实现此功能的方法是创建一个继承自 `CheckBox` 的控件。

Class.png

这样,您只需将 `DontShowAgainCheckBox` 拖放到对话框上,调整您希望显示的文本,即可完成。控件将处理所有其他事情。

在内部,控件无法真正阻止对话框的显示——调用者仍然使用 `ShowDialog()` 来显示对话框,但 `DontShowAgainCheckBox` 一旦显示就会立即关闭对话框,并返回指定的 `DialogResult`:即其 `AutoCloseResult` 属性的值。

然而,这种方法有一个小缺陷。关闭对话框的命令是在窗体的 `Load` 事件处理程序中发出的。这意味着对话框在消失之前会短暂地可见。尽管这不会影响功能本身(对话框在没有用户交互的情况下就消失了),但这种闪烁会破坏对话框确实未被显示的错觉。解决方法是将对话框的 `Opacity` 设置为 0,然后再执行其他任何操作。对话框仍然会短暂出现,但因为它完全透明,您看不见它——错觉得以保持

如果您希望每次自动关闭对话框时都获得相同的 `AutoCloseResult`,只需在设计器中设置一次 `AutoCloseResult` 即可。如果您希望根据用户单击的按钮来关闭对话框,从而获得不同的 `AutoCloseResult`,则可以在相应的按钮事件处理程序中轻松设置该属性。演示项目展示了如何做到这一点。

`Target` 属性保存对控件所在对话框的引用,以便可以连接 `Load` 事件所需的事件处理程序。通常,您无需自行设置 `Target` 属性。当控件被分配给新父控件时,它会自动分配。因此,我将 `Target` 属性设置为不可浏览(通过将 `BrowsableAttribute` 设置为 `false`)。

如果您想重置用户永久关闭对话框的选择,可以使用静态方法 `Reset()`。通过向其提供要重置的对话框实例,可以重置阻止显示对话框的标志。

关注点

`DontShowAgainCheckBox` 需要记住要自动关闭的对话框。我选择了注册表来存储此信息,但您同样可以修改代码以使用文件等。

对于每个对话框,都会使用不同的注册表路径(在 HKEY_CURRENT_USER 下),其模式如下:

SOFTWARE\CompanyName\ProductName\DontShowAgainSettings\Form Type\Form Title

CompanyNameProductName 取自 `Application` 的相应属性。Form Type 是 `Target` 窗体的完整类型名称(包括命名空间)。Form Title 是 `Target` 窗体 `Text` 属性的值。

我没有仅以窗体类名作为依据,因为我想区分同一对话框类的两种不同用法。

有时,对话框类可以配置为执行不同的任务,这样您就不必实现新的对话框类。如果此时更改对话框标题,`DontShowAgainCheckBox` 可以为这两种版本保留不同的状态。我在演示项目中也包含了这方面的示例。

如果您有任何改进建议,请留言。并且,不要忘记投票……

历史

  • 2007年7月21日 - 首次发布。
© . All rights reserved.