2013-10-24 19 views
1

在我的應用程序中,我有一個帶有一些選項卡的TabControl。每個選項卡包含許多組件。如果應用程序正在關閉,我想檢查是否有任何組件的值已更改。如果是這樣,我會詢問用戶是否想要保存它。在FormClosing上保存組件的更改值

我想知道你是如何解決這種情況的(因爲它是應用程序關閉時的標準行爲)。我認爲我有一些標誌(布爾),我爲每個組件設置一個事件ValueChanged。如果方法處理這個事件被觸發,這個標誌被設置爲true。在關閉申請的情況下,我只會檢查標誌是否爲真。

但問題是,有超過30個組件,並創建方法處理每個組件的事件似乎不對我感覺。

+0

一個快速解決方案是使用數據表,當有些東西發生變化時,將其更改爲數據表。在結束事件只是檢查rowstate。 –

+0

但是我仍然需要在每個組件上捕獲ValueChanged事件... – DanielH

+0

您可以使用bindingsource來填充您的控件。 –

回答

0

您在布爾標誌和ValueChanged事件的正確軌道上。據我所知,這是處理這類事情的唯一方法。要做到這一點,您可以簡單地爲事件編寫處理,然後根據需要反覆複製和粘貼組件。

但是,對於分散在30個組件中的有效性問題,您應該考慮滾動您自己的從基類繼承的組件,這些組件會暴露IsDirty屬性或類似屬性。關閉時,您可以循環瀏覽選項卡上的所有控件,看看是否有IsDirty設置爲true

不幸的是,鑑於您已經創建了界面,這兩種方法都不能解決您當前的困境。

0

當您填寫每個控件的文本/值時,還要使用相同的值填寫TAG。然後,您可以將TAG與每個控件的文本/值進行比較,以查看是否有任何更改。

爲了避免必須爲每個控件編寫代碼(當檢查時),您可以在[Tab Page Name] .Controls()中的每個控件上執行for循環。

另一種方法是通過添加IsDirty屬性並覆蓋驗證事件來擴展每個控件。然後你可以設置它,如果它改變了。您可能還想要一種方法來重置IsDirty屬性。另一種方式,我總是綁定到一個類,它只是讓我的代碼更少出錯,並給我智能感知。還可以爲您提供大量的功能,您可以像這樣輕鬆地引入。然後,只需綁定到您的自定義類。

+0

你能向我解釋你最後的想法嗎?我不知道怎樣才能對我有幫助。我使用標籤爲不同的目的,也有組件我不想檢查它們的值是否已經改變,所以標籤和循環不適合我的問題... – DanielH

+0

我已經添加了另一個答案,所以我可以提供一個很好的代碼eaxmple。 – Steve

0

下面是我將如何使用自定義類來執行此操作的示例。這只是讀取csv並寫入它的一個例子,但回答您的問題的關鍵在於「髒」代碼。

Imports System.ComponentModel 
Public Class Form1 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load 
     'On form load, open the file and read the data 
     Using SR As New System.IO.StreamReader("Test.csv") 
      Do While SR.Peek >= 0 
       'Put each line into it's own instance of the class 
       BindingSource1.Add(New MyData(SR.ReadLine)) 
      Loop 
     End Using 
    End Sub 
    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing 
     'When closing, see if any data has been changed and ask to save 
     Dim bDirty As Boolean = False 
     For Each dat As MyData In BindingSource1 
      If dat.IsDirty Then 
       bDirty = True 
       Exit For 
      End If 
     Next 
     If bDirty Then 
      'Example code for saving 
      Select Case MessageBox.Show("Do you want to save your changes?", "Save Changes", MessageBoxButtons.YesNoCancel) 
       Case Windows.Forms.DialogResult.Cancel 
        e.Cancel = True 
       Case Windows.Forms.DialogResult.Yes 
        'Here you should remove the old file, I like to rename it to BAK, 
        ' save the new file, then you can get rid of it. 
        ' Just in case there is a problem saving. 
        If System.IO.File.Exists("Test.csv") Then System.IO.File.Delete("Test.csv") 
        Using SW As New System.IO.StreamWriter("Test.csv", False) 
         For Each dat As MyData In BindingSource1 
          SW.WriteLine(dat) 
         Next 
        End Using 
      End Select 
     End If 
    End Sub 
End Class 
Public Class MyData 
    Implements INotifyPropertyChanged 
    'Event that implements INotifyPropertyChanged. This tells the binding to refresh a property in the UI. 
    Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged 

    Public Sub New(ByVal SomeDataToLoad As String) 
     'Take you data and parse it or whatever into the various properties 
     'This example uses a comma-seperated string 
     Dim sWords As String() = SomeDataToLoad.Split(",") 
     _FirstName = sWords(0) 
     _LastName = sWords(1) 
    End Sub 
    ''' <param name="PropertyName">Case-Sensative property name</param> 
    Public Sub ForcePropertyChanged(ByVal PropertyName As String) 
     RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(PropertyName)) 
    End Sub 
    Private _IsDirty As Boolean 
    Public ReadOnly Property IsDirty As Boolean 
     Get 
      Return _IsDirty 
     End Get 
    End Property 
    ''' <summary>Override the ToString method for getting the data back out, in this case as comma seperated again. You can then write this to file or whatever.</summary> 
    Public Overrides Function ToString() As String 
     Return FirstName & "," & LastName 
    End Function 

    '--Properties you can bind to------------------------------------------------ 
    Private _FirstName As String 
    Public Property FirstName As String 
     Get 
      Return _FirstName 
     End Get 
     Set(value As String) 
      _FirstName = value 
      _IsDirty = True 
      ForcePropertyChanged("FirstName") 
     End Set 
    End Property 
    Private _LastName As String 
    Public Property LastName As String 
     Get 
      Return _LastName 
     End Get 
     Set(value As String) 
      _LastName = value 
      _IsDirty = True 
      ForcePropertyChanged("LastName") 
     End Set 
    End Property 
End Class 

我沒去成如何綁定在這裏,你可以找到所有網站上,但我沒有把數據放到一個BindingSource的,因此其餘的將是容易的。請注意,當表單關閉時,我可以循環查看每條記錄,以便輕鬆查看是否有更改。如果你只有一條記錄,你甚至不需要循環,只要問它是否髒。