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

脏按钮

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.24/5 (17投票s)

2007年4月12日

CPOL

4分钟阅读

viewsIcon

80948

downloadIcon

943

一个能跟踪窗体脏状态的按钮控件。

Screenshot - dirtybutton.gif

引言

当你做一个项目,用户需要填写大量信息时,你通常想知道是否已经进行了更改,以便相应地启用“保存”按钮。通常,你会在代码中放置一个布尔变量(例如:bDirtyBit),并在每个控件的Change事件中输入一些代码(例如:bDirtyBit=TruecmdSave.Enabled=True)。

在我目前工作的项目中,我的窗体有数百个控件,为每个控件的Change事件输入代码非常繁琐。此外,当你添加新控件时,很容易遗漏某个控件。而且,这会产生大量不必要的代码,使真正重要的代码更难阅读。

因此,我决定做一个特殊的按钮控件,它可以自动处理所有这些,而无需任何编码(实际上,是别人提出了这个想法,但不知道如何实现)。这就是我所做的。这个按钮非常基础。它跟踪你窗体上所有重要的控件,并在发生更改时启用按钮。因此,它使你的代码摆脱了上述所有不必要的代码。

该项目还演示了如何使用 Extender Provider 为其他控件添加属性。这比你想象的要容易得多……

这是我第一次向 Code Project 提交,希望一切都好。如果你遇到任何问题,请随时与我联系。

使用代码

该控件的使用非常简单。只需将其放置在你的窗体上,并将以下代码添加到 Form_Load 事件中:

Private Sub Form1_Load(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles MyBase.Load

    DirtyButton1.StartMonitoring()

End Sub

以下基本控件会受到更改监控:CheckBox, ComboBox, DateTimePicker, MaskedTextBox, MonthCalendar, NumericUpDown, RadioButton, RichTextBox, TextBox, Button(可选)。

**** 2.0 版本新增内容 ****

  • 该按钮为可监控控件添加了一个名为 DirtyMonitored 的属性(类似于 Tooltip 组件添加 ToolTip 属性的方式)。如果你窗体上有单个(或多个)你不想纳入监控过程的该类型控件,只需将该属性设置为 False – 瞧:它就被忽略了。
  • 请注意:这些属性实际上并没有添加到控件本身。它们实际上是 DirtyButton 的一部分。因此,它们只在设计时可见。这意味着你不能在运行时使用类似这样的代码: TextBox17.DirtyMonitored=True。你可以调用 DirtyButton.SetDirtyMonitored(Textbox17),但如果在调用 StartMonitoring 方法之后进行调用,它将不起作用。在这种情况下,你可能需要调用 EndMonitoring 然后再调用 StartMonitoring,但我没有尝试过,所以不 100% 确定它是否有效。

    而且,以下控件被监控(因为从什么标准/事件来启用按钮呢?):Label, LinkLabel, ListBox, ListView, NotifyIcon, PictureBox, ProgressBar, ToolTip, TreeView, 和 WebBrowser

    你可以手动设置脏状态,如果上述控件以你认为相关的方式更改,可以使用

    DirtyButton1.SetDirtyState()

    还有一些其他方法和属性也值得了解:ResetDirtyState, IsDirty, SuspendMonitoring, ResumeMonitoring, SetDirtyOnButtonClick 等。所有这些都非常直观,使用起来很简单,并且在演示项目中展示了它们的使用方法。

  • 我“意外地”注意到我的初始控件有一个 bug。如果你将 DirtyButton 放置在 GroupBox 中,那么只有嵌套在该 GroupBox 中的控件会被监控。而不是外部或在其他 GroupBox 中的控件。这是因为我使用了 Parent 属性来确定 DirtyButton 的位置,而不是 FindForm 方法。
  • 但后来我想到:嗯,也许有人喜欢这样,并且希望有两个或更多 GroupBox,每个都有自己的 DirtyButton。其他人可能希望按钮即使在 GroupBox 中也能监控整个窗体。

    所以,我没有修复这个 bug,而是简单地将其变成了一个按钮属性:MonitoringScope,可以设置为 WholeFormParentOnly。这解决了这个问题!

  • 我为 DirtyButton 控件添加了一个 DirtyStateChanged 事件。当按钮更改 DirtyState 时,它会触发,包括从干净变为脏和从脏变为干净。在 EventArgs 中,你可以获取布尔类型的状态以及导致更改的控件。在演示项目中,你可以看到如何找到该控件的名称。
  • 我在 EndMonitoring 例程中做了一些更改。在 1.0 版本中,我只是停止了对控件的监控,但保留了事件处理程序。在此版本中,我决定进行一些清理,现在会移除事件处理程序。
  • 乌兰巴托不再是一个国家,而是一个城市……不过,它确实很远……;-)

未来版本可能的改进

能够将自定义控件和第三方控件添加到监控过程中将很不错,但在此阶段对我来说并非必需。

MonitoredControls、DirtyControls 等的集合,按要求提供……:-)

目前,在运行时添加的控件不会被包含,除非你在它们被添加之后调用 StartMonitoring 方法。但是,你多久会在运行时添加控件一次?

历史

  • 2.0:修复了 bug 并添加了新功能。请参阅上面的文本。
  • 1.0:初始发布。
© . All rights reserved.