Vb.net 检查是否有任何控件已更改,并在表单关闭时保存数据
我们正在使用vb.net/dev express工具。我们有几个控件文本框、组合框等。。。我们不想检查每个更改的值,而是要检查所有控件并检查是否有任何内容已被编辑,然后在表单关闭时保存。下面是我试图实现这一点的一些代码。问题是,虽然技术上可行。。。它使用递归AddDirtyEvent(c),因此当我关闭表单并单击yes保存时。。由于多个控件,它多次调用messagebox。。。如果我把它拿出来,它就不会工作,也检测不到脏的变化。我只是想知道我如何才能让这个工作的方式,我想或者如果有一个更简单的方法Vb.net 检查是否有任何控件已更改,并在表单关闭时保存数据,vb.net,winforms,dirty-checking,dirty-tracking,Vb.net,Winforms,Dirty Checking,Dirty Tracking,我们正在使用vb.net/dev express工具。我们有几个控件文本框、组合框等。。。我们不想检查每个更改的值,而是要检查所有控件并检查是否有任何内容已被编辑,然后在表单关闭时保存。下面是我试图实现这一点的一些代码。问题是,虽然技术上可行。。。它使用递归AddDirtyEvent(c),因此当我关闭表单并单击yes保存时。。由于多个控件,它多次调用messagebox。。。如果我把它拿出来,它就不会工作,也检测不到脏的变化。我只是想知道我如何才能让这个工作的方式,我想或者如果有一个更简单的方
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
代码中处理事件并设置脏标志的部分工作正常
您的消息框出现多次,因为您正在调用
Me.Close
事件处理程序中的FormClosing
。调用Close
再次递归触发FormClosing事件。只需移除Me。关闭;表单已经关闭。作为一名ex-MS access程序员,我也非常渴望为vb.net开发一个表单脏属性的实现,我发现它更方便用户(我的用户已经习惯了)检测窗体上控件的更改或留下脏窗体并请求确认,而不是使用经典的编辑和保存按钮。
我以前在库中为textbox、combobox、listbox等创建了自定义控件。。。因为我喜欢有焦点的控件有不同的背景和缩放文本的能力等等
所以我添加了(文本框代码):
表单保存将调用Formdirty(me)=False
它仍然在测试阶段,仍然没有从用户那里得到确认,等等。。。
它是有效的,但由于我对.net编程非常陌生,所以欢迎任何评论或批评
rgds
> 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
> #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