カスタムクラスを使用してこれを行う方法の例を次に示します。これは 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 にデータを入れたので、残りは簡単です。フォームが閉じているときに、すべてのレコードをループして、変更があったかどうかを簡単に確認できることに注意してください。レコードが 1 つしかない場合は、ループする必要さえありません。それがダーティかどうかを確認するだけです。