表单更改控件






4.79/5 (12投票s)
一个允许您监视窗体上所有控件的组件,
引言
此控件是一个快速且简单的组件(基于 System.ComponentModel.IExtenderProvider
),它允许您列出所有已更改的组件,例如,以便您可以决定是否需要保存表单。
背景
这是一个快速且简单的解决方案,用于解决“如何知道表单上的任何数据是否已更改”的问题。它允许您更改用户界面以显示已更改,并决定需要保存的内容。

Using the Code
该组件有一个属性:ControlsThatHaveChanged
,它是一个泛型列表,其中包含自上次重置以来数据已更改的所有控件。如果此列表不为空,则表单已更改,需要保存。
有一个方法:ResetDirtyFlags
,它允许您重置已更改的控件列表 - 在填充表单或保存数据时调用此方法。
此外,每当正在监视更改的控件发生更改或更改回其初始状态时,都会引发一个事件。
VB.NET
Private Sub FormChangedComponent1_FormControlChanged(ByVal sender As Object, _
ByVal e As FormChangedEventArgs) _
Handles FormChangedComponent1.FormControlChanged
If TypeOf e.ControlChanged Is TextBox Then
If e.Changed Then
e.ControlChanged.BackColor = Color.Yellow
Else
e.ControlChanged.BackColor = Color.White
End If
End If
End Sub
C#
void formChangedComponent1_MonitoredControlChanged(object sender, FormChangedEventArgs e)
{
if (e.ControlChanged is TextBox)
{
if (e.Changed)
{
e.ControlChanged.BackColor = Color.Yellow;
}
else
{
e.ControlChanged.BackColor = Color.White;
}
}
}
工作原理
该组件实现了 Implements System.ComponentModel.IExtenderProvider
以扩展表单上的控件,并为这些控件中的每一个提供三个新的属性

MonitorForChanges
- 设置为 True
以监视控件的更改
ChangeEventToMonitor
- 将其设置为要监视的事件的名称(例如“ValueChanged
”或控件的事件名称)
ValueNameToMonitor
- 将其设置为表示控件值的属性的名称(例如,textbox
的“Text
”)
请注意,这些属性区分大小写,这可能会让粗心的人掉入陷阱。
当一个组件具有设置为 True
的此扩展属性时,该组件会将其添加到指定的“Changed
”事件处理程序中,并且当该事件触发时,它会更新一个内部泛型集合,其中包含已更改的组件。
该组件可以在保存事件发生后或记录被刷新时重置(即,将所有控件标记为未更改)。
VB.NET
Public Sub SetMonitorForChanges(ByVal ctl As Control, ByVal value As Boolean)
If value Then
If Not _ControlChanged.ContainsKey(ctl) Then
_ControlChanged.Add(ctl, False)
Dim evi As System.Reflection.EventInfo
evi = ctl.GetType.GetEvent(Me.GetChangeEventName(ctl))
If Not (evi Is Nothing) Then
'\\ Get the method that adds a handler to the changed event
Dim mi As System.Reflection.MethodInfo
mi = evi.GetAddMethod(False)
'\\ add a handler to that changed event
mi.Invoke(ctl, New Object() {Me.ChangeEventhandler})
End If
End If
Else
If _ControlChanged.ContainsKey(ctl) Then
_ControlChanged.Remove(ctl)
End If
End If
End Sub
C#
private void ResetMonitoringState()
{
System.Reflection.EventInfo evi;
Type ctlType = _ctlToMonitor.GetType();
evi = ctlType.GetEvent(_ChangeEventName);
if (_MonitoringEvent )
{
// Remove the event handler from the control
if ( evi != null)
{
System.Reflection.MethodInfo mi = evi.GetRemoveMethod(false);
mi.Invoke(_ctlToMonitor, new object[] { this.ChangeEventhandler() });
}
}
if (_Monitor )
{
// Add the event handler to the control
if (evi != null)
{
System.Reflection.MethodInfo mi = evi.GetAddMethod(false);
mi.Invoke(_ctlToMonitor, new object[] { this.ChangeEventhandler() });
_MonitoringEvent = true;
}
}
}
历史
- 2007-06-28
- 首次发布
- 2007-07-03
- 添加了属性来指定正在监视的事件和值,并更改了代码以使用属性的哈希值进行真正的更改检查
- 2007-09-13
- 添加了一个事件,每当正在监视的控件发生更改或更改回其先前状态时都会触发该事件
- 2008-05-26
- 添加了 C# 代码版本