检查是否有任何控件已更改并在表单关闭时保存数据
Check if any control has changed and save data upon form closing
我们正在使用 vb.net/dev 快速工具。我们有几个控件文本框、组合等...而不是检查每个更改的值,我们想要遍历所有控件并检查是否有任何内容已被编辑,然后在关闭表单时保存。下面是我试图完成的一些代码。问题是,虽然它在技术上有效......它使用递归 AddDirtyEvent(c) ,所以当我关闭表单并单击“是”保存时......由于有多个控件,它会多次调用该消息框......如果我接受它out ,它不会工作并检测到脏变化。我只是想知道我怎样才能让它按照我想要的方式工作,或者是否有更简单的方法......
Dim is_Dirty As Boolean = False
Private Sub AddDirtyEvent(ByVal ctrl As Control)
For Each c As Control In ctrl.Controls
If TypeOf c Is TextEdit Then
Dim tb As TextEdit = CType(c, TextEdit)
AddHandler tb.EditValueChanged, AddressOf SetIsDirty
End If
'If TypeOf c Is ComboBoxEdit Then
' Dim cb As ComboBoxEdit = CType(c, ComboBoxEdit)
' AddHandler cb.SelectedIndexChanged, AddressOf SetIsDirty
'End If
If c.Controls.Count > 0 Then
AddDirtyEvent(c)
End If
Next
End Sub
Private Sub SetIsDirty(ByVal sender As System.Object, ByVal e As System.EventArgs)
is_Dirty = True
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
If is_Dirty = True Then
Dim dr As DialogResult = MessageBox.Show("Do you want save changes before leaving?", "Closing Well Info", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2)
If dr = Windows.Forms.DialogResult.Yes Then
SimpleButtonSave.PerformClick()
Me.Close()
End If
End If
End Sub
处理事件和设置脏标志的代码部分工作正常。
您的 MessageBox 出现多次,因为您在 FormClosing
事件处理程序中调用 Me.Close
。调用 Close
再次触发 FormClosing 事件 - 递归地。只需删除 Me.Close
;表格已经关闭。
作为一名前 MS 访问程序员,我也非常渴望为 vb.net 开发一个脏表单 属性 的实现,我发现它对用户更友好(我的用户已经习惯了) ) 来检测表单上控件的更改或留下脏表单并要求确认而不是经典的编辑和保存按钮。
我之前在库中为文本框、组合框、列表框等创建了自定义控件...因为我喜欢具有焦点的控件具有不同的背景和缩放文本的能力等...
所以我给他们添加了(文本框代码):
> Protected Overrides Sub OnModifiedChanged(e As EventArgs)
> MyBase.OnModifiedChanged(e)
> If _DirtyEnabled and Me.Modified Then FormDirty(Me) = Me.Modified
> End Sub
> Private _DirtyEnabled As Boolean = False
> <Category("Misc"), Description("When Enabled triggers Dirty event for form"), Browsable(True)> _
> Public Property DirtyEnabled As Boolean
> Get
> Return _DirtyEnabled
> End Get
> Set(value As Boolean)
> DirtyEnabled = value
> End Set
> End Property
这是针对文本框的,对于组合框和列表框,我使用了 SelectIndexChanged 事件。
如果 DirtyEnabled 属性 设置为 True,那么任何更改都会触发 FormDirty 属性 的调用。
然后在库的 public 模块中:
> #Region "Dirty"
> Private Structure FormInfo ' used in DirtyForm dictionary to keep a list of dirty forms
> Dim Name As String
> Dim Time As Date
> Dim Ctrl As String
> End Structure
> Private DirtyForms As New Dictionary(Of IntPtr, FormInfo) ' key = form handle as the form could be opened more then once, value FormInfo
>
> Public Property FormDirty(frm As Form) As Boolean
> Get
> If DirtyForms.Count > 0 Then
> Return DirtyForms.ContainsKey(frm.Handle)
> Else
> Return False
> End If
> End Get
> Set(IsDirty As Boolean)
> EditDirtyForms(frm, IsDirty)
> End Set
> End Property
>
> Public Property FormDirty(Ctrl As Control) As Boolean
> Get
> If DirtyForms.Count > 0 Then
> Return DirtyForms.ContainsKey(Ctrl.FindForm.Handle)
> Else
> Return False
> End If
> End Get
> Set(IsDirty As Boolean)
> EditDirtyForms(Ctrl.FindForm, IsDirty, Ctrl.Name)
> End Set
> End Property
>
> Private Sub EditDirtyForms(frm As Form, IsDirty As Boolean, Optional CtrlName As String = Nothing)
> If IsDirty Then
> If DirtyForms.Count = 0 OrElse Not DirtyForms.ContainsKey(frm.Handle) Then
> Dim Info As New FormInfo With {.Name = frm.Name, .Time = Now, .Ctrl = CtrlName}
> DirtyForms.Add(frm.Handle, Info)
> End If
> ElseIf DirtyForms.Count > 0 Then
> If DirtyForms.ContainsKey(frm.Handle) Then DirtyForms.Remove(frm.Handle)
> End If
> End Sub
>
> Public Function DirtyFormList() As String
> Dim p As New FormInfo, s As String = String.Empty
> If DirtyForms.Count > 0 Then
> For Each f As KeyValuePair(Of IntPtr, FormInfo) In DirtyForms
> s &= f.Value.Name & cSpace & If(f.Value.Ctrl, String.Empty) & ": " & f.Value.Time & vbNewLine
> Next
> End If
> Return s
> End Function
>
> Public Function DirtyFormCount() As Integer
> Return DirtyForms.Count
> End Function
> #End Region
表单保存会调用 Formdirty(me) = False
它仍处于测试阶段,仍然错过了向用户询问确认等......
它有效,但由于我是 .net 编程的新手,非常欢迎任何评论或批评。
rgds
我们正在使用 vb.net/dev 快速工具。我们有几个控件文本框、组合等...而不是检查每个更改的值,我们想要遍历所有控件并检查是否有任何内容已被编辑,然后在关闭表单时保存。下面是我试图完成的一些代码。问题是,虽然它在技术上有效......它使用递归 AddDirtyEvent(c) ,所以当我关闭表单并单击“是”保存时......由于有多个控件,它会多次调用该消息框......如果我接受它out ,它不会工作并检测到脏变化。我只是想知道我怎样才能让它按照我想要的方式工作,或者是否有更简单的方法......
Dim is_Dirty As Boolean = False
Private Sub AddDirtyEvent(ByVal ctrl As Control)
For Each c As Control In ctrl.Controls
If TypeOf c Is TextEdit Then
Dim tb As TextEdit = CType(c, TextEdit)
AddHandler tb.EditValueChanged, AddressOf SetIsDirty
End If
'If TypeOf c Is ComboBoxEdit Then
' Dim cb As ComboBoxEdit = CType(c, ComboBoxEdit)
' AddHandler cb.SelectedIndexChanged, AddressOf SetIsDirty
'End If
If c.Controls.Count > 0 Then
AddDirtyEvent(c)
End If
Next
End Sub
Private Sub SetIsDirty(ByVal sender As System.Object, ByVal e As System.EventArgs)
is_Dirty = True
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
If is_Dirty = True Then
Dim dr As DialogResult = MessageBox.Show("Do you want save changes before leaving?", "Closing Well Info", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2)
If dr = Windows.Forms.DialogResult.Yes Then
SimpleButtonSave.PerformClick()
Me.Close()
End If
End If
End Sub
处理事件和设置脏标志的代码部分工作正常。
您的 MessageBox 出现多次,因为您在 FormClosing
事件处理程序中调用 Me.Close
。调用 Close
再次触发 FormClosing 事件 - 递归地。只需删除 Me.Close
;表格已经关闭。
作为一名前 MS 访问程序员,我也非常渴望为 vb.net 开发一个脏表单 属性 的实现,我发现它对用户更友好(我的用户已经习惯了) ) 来检测表单上控件的更改或留下脏表单并要求确认而不是经典的编辑和保存按钮。 我之前在库中为文本框、组合框、列表框等创建了自定义控件...因为我喜欢具有焦点的控件具有不同的背景和缩放文本的能力等...
所以我给他们添加了(文本框代码):
> Protected Overrides Sub OnModifiedChanged(e As EventArgs)
> MyBase.OnModifiedChanged(e)
> If _DirtyEnabled and Me.Modified Then FormDirty(Me) = Me.Modified
> End Sub
> Private _DirtyEnabled As Boolean = False
> <Category("Misc"), Description("When Enabled triggers Dirty event for form"), Browsable(True)> _
> Public Property DirtyEnabled As Boolean
> Get
> Return _DirtyEnabled
> End Get
> Set(value As Boolean)
> DirtyEnabled = value
> End Set
> End Property
这是针对文本框的,对于组合框和列表框,我使用了 SelectIndexChanged 事件。 如果 DirtyEnabled 属性 设置为 True,那么任何更改都会触发 FormDirty 属性 的调用。 然后在库的 public 模块中:
> #Region "Dirty"
> Private Structure FormInfo ' used in DirtyForm dictionary to keep a list of dirty forms
> Dim Name As String
> Dim Time As Date
> Dim Ctrl As String
> End Structure
> Private DirtyForms As New Dictionary(Of IntPtr, FormInfo) ' key = form handle as the form could be opened more then once, value FormInfo
>
> Public Property FormDirty(frm As Form) As Boolean
> Get
> If DirtyForms.Count > 0 Then
> Return DirtyForms.ContainsKey(frm.Handle)
> Else
> Return False
> End If
> End Get
> Set(IsDirty As Boolean)
> EditDirtyForms(frm, IsDirty)
> End Set
> End Property
>
> Public Property FormDirty(Ctrl As Control) As Boolean
> Get
> If DirtyForms.Count > 0 Then
> Return DirtyForms.ContainsKey(Ctrl.FindForm.Handle)
> Else
> Return False
> End If
> End Get
> Set(IsDirty As Boolean)
> EditDirtyForms(Ctrl.FindForm, IsDirty, Ctrl.Name)
> End Set
> End Property
>
> Private Sub EditDirtyForms(frm As Form, IsDirty As Boolean, Optional CtrlName As String = Nothing)
> If IsDirty Then
> If DirtyForms.Count = 0 OrElse Not DirtyForms.ContainsKey(frm.Handle) Then
> Dim Info As New FormInfo With {.Name = frm.Name, .Time = Now, .Ctrl = CtrlName}
> DirtyForms.Add(frm.Handle, Info)
> End If
> ElseIf DirtyForms.Count > 0 Then
> If DirtyForms.ContainsKey(frm.Handle) Then DirtyForms.Remove(frm.Handle)
> End If
> End Sub
>
> Public Function DirtyFormList() As String
> Dim p As New FormInfo, s As String = String.Empty
> If DirtyForms.Count > 0 Then
> For Each f As KeyValuePair(Of IntPtr, FormInfo) In DirtyForms
> s &= f.Value.Name & cSpace & If(f.Value.Ctrl, String.Empty) & ": " & f.Value.Time & vbNewLine
> Next
> End If
> Return s
> End Function
>
> Public Function DirtyFormCount() As Integer
> Return DirtyForms.Count
> End Function
> #End Region
表单保存会调用 Formdirty(me) = False 它仍处于测试阶段,仍然错过了向用户询问确认等...... 它有效,但由于我是 .net 编程的新手,非常欢迎任何评论或批评。
rgds