2

我们正在使用 vb.net/dev express 工具。我们有几个控件文本框、组合等...而不是检查每个更改的值,我们想要遍历所有控件并检查是否已编辑任何内容,然后在表单关闭时保存。下面是我尝试完成的一些代码。问题是,虽然它在技术上有效......它使用递归 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
4

2 回答 2

1

处理事件和设置脏标志的代码部分工作正常。

您的 MessageBox 出现多次,因为您Me.CloseFormClosing事件处理程序中调用。调用Close再次触发 FormClosing 事件 - 递归。只需删除Me.Close; 表格已经关闭。

于 2016-04-08T22:51:47.497 回答
0

作为一名前 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 属性的调用。然后在库的公共模块中:

>    #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

于 2017-01-13T15:47:17.677 回答