在 WinForms 应用程序中管理数据(无需数据库)
本文提供了一种构建应用程序的方法,该应用程序可在不依赖数据库的情况下收集、存储和检索数据。

引言
本文提供了一种构建应用程序的方法,该应用程序可在不依赖数据库的情况下收集、存储和检索数据。如果您需要存储少量数据,您的用户将不会与其他用户共享数据,并且您不需要后端有一个功能完善的关系数据库,那么本文可能会引起您的兴趣。
本文围绕一个演示项目构建,该项目允许用户存储在鸟类观察期间收集的一些信息;当然,相同的方法也可以用于处理联系人信息、库存、邮票收藏、硬币收藏、电影收藏,或者您想跟踪的任何其他内容。

该应用程序提供以下功能:
- 创建鸟类数据文件。
- 将鸟类添加到鸟类数据文件中。
- 从鸟类数据文件中删除鸟类。
- 按名称搜索特定鸟类。
- 创建和编辑鸟类详细信息。
- 鸟名
- 鸟的性别
- 鸟类地点
- 鸟类行为
- 观察日期
- 观察时间
- 鸟的照片
- 保存鸟类数据文件。
- 重新打开鸟类数据文件。
- 浏览鸟类数据文件中的所有鸟类。
- 查看鸟类数据文件中的所有鸟类列表。
应用程序中使用的方法仅代表一种做事方式。与 .NET 世界中的大多数事物一样,有几种替代方案,如果您愿意,可以修改代码以使用其他替代方案之一来处理数据。


入门
下载中包含一个解决方案,该解决方案包含一个名为 BirdWatch_VB
的 WinForms 项目;该项目包含三个窗体(主窗体、搜索窗体和用于显示鸟类总列表的窗体)、一个名为 BirdData.vb 的可序列化类(用于包含鸟类相关数据),以及一个名为 FileSerializer.vb 的类,其中包含两个 static
方法,用于将鸟类数据序列化和反序列化(写入和读取文件)。
如果您在 Visual Studio 2008 中打开附加的项目;您应该会在解决方案资源管理器中看到以下内容:

代码:BirdData.vb
BirdData
类是用于存储应用程序中所有鸟类相关数据的容器类。虽然此演示使用鸟类数据,但可以轻松地将其替换为您更有用的内容。
该类以常规的默认 imports
开始
Imports System
Imports System.Drawing
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
下一部分包含类声明。请注意,该类声明为 serializable
;serializable
属性表示该类可以被序列化。
<Serializable()> _
Public Class BirdData
类中定义的区域声明了类内部使用的成员变量;所有对外公开的成员变量都通过 public
属性进行访问。
#Region "Member Variables"
Private mId As System.Guid
Private mBirdName As String
Private mGender As String
Private mLocation As String
Private mBehaviorObserved As String
Private mDateViewed As DateTime
Private mTimeViewed As DateTime
Private mPicture As Byte()
Private mPictureName As String
#End Region
类中的下一段代码包含构造函数。定义了两个构造函数;一个默认构造函数,它创建一个类的新实例并为其分配一个内部 ID(作为 Guid
)。第二个构造函数接受一个鸟名作为参数,在调用时,此构造函数会生成一个 ID 并将鸟名属性分配给鸟名成员变量。
#Region "Constructor"
Public Sub New()
mId = Guid.NewGuid()
End Sub
Public Sub New(ByVal birdName)
mId = Guid.NewGuid()
mBirdName = birdName
End Sub
#End Region
此类代码的最后一部分包含在 properties
区域中;该区域包含所有用于访问成员变量的 properties
。请注意,由于 ID 值始终由构造函数设置,因此该属性不提供 public
接口来将 Guid
设置为新值。
#Region "Properties"
Public ReadOnly Property ID() As Guid
Get
Return mId
End Get
End Property
Public Property BirdName() As String
Get
Return mBirdName
End Get
Set(ByVal value As String)
mBirdName = value
End Set
End Property
Public Property Gender() As String
Get
Return mGender
End Get
Set(ByVal value As String)
mGender = value
End Set
End Property
Public Property Location() As String
Get
Return mLocation
End Get
Set(ByVal value As String)
mLocation = value
End Set
End Property
Public Property BehaviorObserved() As String
Get
Return mBehaviorObserved
End Get
Set(ByVal value As String)
mBehaviorObserved = value
End Set
End Property
Public Property DateViewed() As Date
Get
Return mDateViewed
End Get
Set(ByVal value As Date)
mDateViewed = value
End Set
End Property
Public Property TimeViewed() As Date
Get
Return mTimeViewed
End Get
Set(ByVal value As Date)
mTimeViewed = value
End Set
End Property
Public Property Picture() As Byte()
Get
Return mPicture
End Get
Set(ByVal value As Byte())
mPicture = value
End Set
End Property
Public Property PictureName() As String
Get
Return mPictureName
End Get
Set(ByVal value As String)
mPictureName = value
End Set
End Property
#End Region
End Class
以上是 BirdData
类的说明。
代码:主应用程序窗体 (Form1.vb)
鸟类追踪器主窗体包含以下控件:
- Menu
- 文件
- 新建
- 打开
- 保存
- 另存为
- 退出
- 视图
- 列出所有鸟类
- 工具栏
- 添加鸟类
- 删除鸟类
- 查找鸟类
- 保存鸟类数据
- 导航到上一只鸟
- 导航到下一只鸟
- 退出应用程序
- 鸟名文本框控件
- 鸟的性别组合框
- 鸟类地点多行文本框
- 鸟类行为多行文本框
- 观察日期日期时间选择器
- 观察时间日期时间选择器
- 组容器
- 图片框
- 设置图片按钮

该类以常规的默认 imports
开始
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.IO
Imports System.Windows.Forms
下一部分包含类声明。
''' <summary>
''' A simple project used to maintain data about a
''' collection of birds (could be anything), and to
''' display that data to the user, persist the data,
''' and allow the user to recover and modify the
''' data without using a database.
''' </summary>
Public Class Form1
类中定义的区域声明了类内部使用的成员变量;所有对外公开的成员变量都通过 public
属性进行访问。每个声明旁边的注释描述了它的用途。
#Region "Variable Declarations"
Private birds As List(Of BirdData) ' a container for the bird collection
Private currentBird As BirdData ' the current bird (displayed)
Private currentFilePath As String ' the path to the bird data file
Private currentPosition As Integer ' the position within the bird list
Private dirtyForm As Boolean ' mark the form dirty when changed
#End Region
类中的下一段代码包含构造函数。在初始化时,应用程序会创建一个新的鸟类数据列表,创建一个新的鸟类数据对象,将日期和时间选择器控件设置为当前日期,将当前位置指示器设置为零,并将脏窗体 Boolean
设置为 false
。
#Region "Constructor"
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
' create new bird data list
' ready to write data
birds = New List(Of BirdData)()
currentBird = New BirdData()
birds.Add(currentBird)
' set the date time pickers to now
dtpDate.Value = DateTime.Now
dtpTime.Value = DateTime.Now
' init current position to zero
currentPosition = 0
' mark form as not dirty
dirtyForm = False
End Sub
#End Region
下一个代码区域称为 Housekeeping
。此区域包含用于操作应用程序的一些基本功能。第一个代码部分是用于退出工具栏按钮的点击事件处理程序;此函数仅调用退出菜单项选项的事件处理程序,而不是在两个函数中复制代码。
#Region "Housekeeping"
''' <summary>
''' Exit the application
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub exitToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles exitToolStripMenuItem.Click
If dirtyForm = True Then
If MessageBox.Show(Me, "You have not saved the current bird data; " + _
"would you like to save before exiting?", _
"Save Current Data", MessageBoxButtons.YesNo) = _
System.Windows.Forms.DialogResult.Yes Then
saveToolStripMenuItem_Click(Me, New EventArgs())
End If
Else
Application.Exit()
End If
End Sub
下一个代码部分是退出菜单选项的点击事件处理程序。此代码首先检查窗体是否被标记为脏(基于用户在应用程序运行期间所做的更改);如果窗体是脏的,并且用户尝试退出应用程序,将向用户显示一个消息框,询问他们是否希望在不保存的情况下退出应用程序。如果用户表示他们希望在退出应用程序之前保存,应用程序将向用户显示保存文件对话框;否则,应用程序将退出。
''' <summary>
''' Exit the application
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub tsbExit_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles tsbExit.Click
' call the menu function
exitToolStripMenuItem_Click(Me, New EventArgs())
End Sub
下一个方法用于清除主窗体控件中显示的所有信息。
''' <summary>
''' Clear all form fields
''' </summary>
Public Sub ClearForm()
dirtyForm = True
txtBirdName.Text = String.Empty
txtLocation.Text = String.Empty
txtBehavior.Text = String.Empty
cboGender.SelectedIndex = -1
dtpDate.Value = DateTime.Now
dtpTime.Value = DateTime.Now
picBird.Image = Nothing
End Sub
窗体中包含的下一个函数用于设置与当前鸟类关联的图像。由于我们正在向当前鸟类数据实例添加新数据,因此窗体被标记为脏——这将允许用于退出应用程序的函数检查当前数据是否需要在退出应用程序之前保存。该函数使用打开文件对话框允许用户设置图像文件的路径;一旦设置了文件路径;该函数打开文件,将其转换为字节数组,并将其存储在当前鸟类数据对象的图像属性中。该函数最后设置窗体的图像以显示选定的鸟类图片。
''' <summary>
''' Load the image into the picture box
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnSetImage_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnSetImage.Click
dirtyForm = True
Dim imageFilePath As String = String.Empty
Dim OpenFileDialog1 As New OpenFileDialog()
OpenFileDialog1.Title = "Open Image File"
OpenFileDialog1.Filter = "JPEG Documents (*.jpg)|*.jpg|Gif Files|*.gif"
If OpenFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.Cancel
Then
Return
End If
imageFilePath = OpenFileDialog1.FileName
If String.IsNullOrEmpty(imageFilePath) Then
Return
End If
If System.IO.File.Exists(imageFilePath) = False Then
Return
End If
Try
' convert Image to byte array and save in
Dim fsImage As System.IO.FileStream = Nothing
fsImage = System.IO.File.Open(imageFilePath, FileMode.Open,
FileAccess.Read)
Dim bArrImage(fsImage.Length) As Byte
fsImage.Read(bArrImage, 0, Convert.ToInt32(fsImage.Length))
fsImage.Close()
currentBird.Picture = bArrImage
currentBird.PictureName = imageFilePath
Dim ms As New MemoryStream(bArrImage)
picBird.Image = Image.FromStream(ms)
ms.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message, "Error Storing Image")
End Try
End Sub
下一个函数用于处理“新建”菜单选项的点击事件;此函数首先检查脏窗体 Boolean
,以查看是否应在开始新的鸟类数据文件之前保存当前数据。如果当前窗体是脏的;将提示用户保存当前数据,否则,将创建一个新的鸟类数据集合,并将窗体中所有先前的条目清除。
''' <summary>
''' Create a new bird data file
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub newToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles newToolStripMenuItem.Click
If dirtyForm = True Then
If (MessageBox.Show(Me, "You have not saved the current bird data; " + _
"would you like to save before starting a new " + _
"bird database?", "Save Current Data", _
MessageBoxButtons.YesNo) = _
System.Windows.Forms.DialogResult.Yes) Then
saveToolStripMenuItem_Click(Me, New EventArgs())
Else
' discard and start new document
birds = New List(Of BirdData)()
ClearForm()
End If
Else
' start new document
birds = New List(Of BirdData)()
ClearForm()
End If
End Sub
打开文件菜单选项的点击事件处理程序紧随其后;此函数在打开新的鸟类数据文件到应用程序之前也检查是否为脏窗体。如果窗体不是脏的,应用程序将调用 Open
函数,该函数将允许用户导航并打开一个文件进行查看或编辑。
''' <summary>
''' Open an existing bird data file
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub openStripMenuItem2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles openStripMenuItem2.Click
If dirtyForm = True Then
If (MessageBox.Show(Me, "You have not saved the current bird data; " + _
"would you like to save before opening a different " + _
"bird database?", "Save Current Data", _
MessageBoxButtons.YesNo) = _
System.Windows.Forms.DialogResult.Yes) Then
saveToolStripMenuItem_Click(Me, New EventArgs())
Else
Open()
End If
Else
Open()
End If
End Sub
接下来,打开方法使用打开文件对话框控件允许用户导航并选择一个鸟类数据文件。一旦选定,文件将被反序列化到本地鸟类集合并可供显示。
''' <summary>
''' Open an existing bird data file
''' </summary>
Public Sub Open()
Dim OpenFileDialog1 As New OpenFileDialog()
OpenFileDialog1.Title = "Open BRD Document"
OpenFileDialog1.Filter = "BRD Documents (*.brd)|*.brd"
If OpenFileDialog1.ShowDialog() = _
System.Windows.Forms.DialogResult.Cancel Then
Return
End If
currentFilePath = OpenFileDialog1.FileName
If String.IsNullOrEmpty(currentFilePath) Then
Return
End If
If System.IO.File.Exists(currentFilePath) = False Then
Return
End If
birds = FileSerializer.Deserialize(currentFilePath)
' Load bird at position zero
If birds.Count <> 0 Then
currentBird = birds.ElementAt(0)
LoadCurrentBird()
dirtyForm = False
End If
End Sub
保存菜单选项点击事件处理程序就在其后面。此函数使用保存文件对话框允许用户设置文件名或文件路径。一旦设置了文件路径,应用程序就会将鸟类集合中包含的数据序列化,并将其保存到磁盘。
''' <summary>
''' Save the existing bird data file
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub saveToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles saveToolStripMenuItem.Click
SaveCurrentBird()
If String.IsNullOrEmpty(currentFilePath) Then
Dim SaveFileDialog1 As New SaveFileDialog()
Try
SaveFileDialog1.Title = "Save BRD Document"
SaveFileDialog1.Filter = "BRD Documents (*.brd)|*.brd"
If SaveFileDialog1.ShowDialog() = _
System.Windows.Forms.DialogResult.Cancel Then
Return
End If
Catch
Return
End Try
currentFilePath = SaveFileDialog1.FileName
End If
If String.IsNullOrEmpty(currentFilePath) Then
MessageBox.Show("File path is not set.", "Save Error")
Return
End If
FileSerializer.Serialize(currentFilePath, birds)
MessageBox.Show("File " + currentFilePath + " saved.", "File Saved")
dirtyForm = False
End Sub
下一段代码与保存非常相似;它允许用户使用替换名称将当前鸟类数据文件保存到本地硬件。
''' <summary>
''' Save the existing bird data file with
''' a new file name
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub saveAsToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles saveAsToolStripMenuItem.Click
Dim SaveFileDialog1 As New SaveFileDialog()
Try
SaveFileDialog1.Title = "Save BRD Document"
SaveFileDialog1.Filter = "BRD Documents (*.brd)|*.brd"
If SaveFileDialog1.ShowDialog() = _
System.Windows.Forms.DialogResult.Cancel Then
Return
End If
Catch
Return
End Try
currentFilePath = SaveFileDialog1.FileName
If String.IsNullOrEmpty(currentFilePath) Then
Return
End If
FileSerializer.Serialize(currentFilePath, birds)
MessageBox.Show("File " + currentFilePath + " saved.", "File Saved.")
dirtyForm = False
End Sub
工具栏的保存按钮紧随其后;它仅调用保存菜单项点击事件来保存鸟类数据文件。
''' <summary>
''' Save the existing bird data file
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub tsbSave_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles tsbSave.Click
saveToolStripMenuItem_Click(Me, New EventArgs())
End Sub
保存当前鸟类函数用于将当前鸟类数据对象的值设置为与窗体控件的内容匹配。
''' <summary>
''' Set the current bird values to the form content
''' if the user navigates off the current bird, it will
''' save the content
''' </summary>
Private Sub SaveCurrentBird()
If Not String.IsNullOrEmpty(txtBirdName.Text) Then
Try
currentBird.BirdName = txtBirdName.Text
currentBird.Location = txtLocation.Text
currentBird.BehaviorObserved = txtBehavior.Text
currentBird.Gender = cboGender.Text
currentBird.DateViewed = dtpDate.Value
currentBird.TimeViewed = dtpTime.Value
' bird image byte array is set for current
' bird when image is set
Catch ex As Exception
MessageBox.Show(ex.Message, "Error")
End Try
End If
End Sub
#End Region
下一个区域称为 Bird Data Management
;本节包含用于管理鸟类数据和鸟类数据集合的方法。此区域中的第一个函数用于将新鸟添加到集合中。该函数保存当前鸟类,创建一个新的空鸟类对象,将新的鸟类数据对象添加到鸟类集合中,然后将窗体标记为脏。
#Region "Bird Data Management"
''' <summary>
''' Add a new bird to the bird data list
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub tsbAdd_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles tsbAdd.Click
SaveCurrentBird()
currentBird = New BirdData()
ClearForm()
birds.Add(currentBird)
dirtyForm = True
End Sub
下一个函数用于从集合中删除鸟类。删除鸟类后;当前位置将更新,并且窗体将使用替换的鸟类信息重新加载。
''' <summary>
''' Remove the current bird from the bird
''' from the bird data list
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub tsbRemoveBird_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles tsbRemoveBird.Click
birds.RemoveAt(currentPosition)
If currentPosition = 0 Then
currentPosition += 1
Else
currentPosition -= 1
currentBird = birds(currentPosition)
LoadCurrentBird()
dirtyForm = True
End If
End Sub
下一个函数用于支持查找特定鸟类。当点击事件处理程序执行时,将创建一个查找窗体(Form3
)的新实例,并设置查找窗体 BirdNameUpdated
事件的事件处理程序。
''' <summary>
''' Find a specific bird
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub tsbFindBird_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles tsbFindBird.Click
Dim f As New Form3(birds)
AddHandler f.BirdNameUpdated, AddressOf FindBird
f.Show()
End Sub
下一个函数用于按名称查找特定鸟类。当查找窗体引发事件,指示用户想要查找集合中具有特定名称的鸟类时,此函数将遍历集合直到找到匹配项,然后它将该鸟类设置为当前鸟类并更新窗体以显示该鸟类的信息。
''' <summary>
''' Bird finder code
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub FindBird(ByVal sender As Object, _
ByVal e As BirdNameUpdateEventArgs)
Dim i As Integer
For i = 0 To birds.Count - 1
If birds(i).BirdName = e.BirdName Then
currentBird = birds(i)
LoadCurrentBird()
currentPosition = i
End If
Next
End Sub
下一个函数用于显示一个包含当前鸟类数据列表中所有鸟类的窗体。Form2
包含一个数据网格视图控件,它接受一个鸟类数据列表作为构造函数的参数。当创建窗体并传递当前鸟类数据的副本时,该数据将绑定到数据网格视图控件并显示给用户。
''' <summary>
''' List all of the birds
''' in the bird data file
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub listAllBirdsToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles
listAllBirdsToolStripMenuItem.Click
Dim f As New Form2(birds)
f.Show()
End Sub
下一个函数在当前鸟类更改时调用。它从当前鸟类对象重新加载所有窗体控件。
''' <summary>
''' Load the current bird into the form
''' </summary>
Private Sub LoadCurrentBird()
Try
txtBirdName.Text = currentBird.BirdName
txtLocation.Text = currentBird.Location
txtBehavior.Text = currentBird.BehaviorObserved
Catch
End Try
Try
cboGender.Text = currentBird.Gender
Catch
End Try
Try
dtpDate.Value = currentBird.DateViewed
Catch
End Try
Try
dtpTime.Value = currentBird.TimeViewed
Catch
End Try
Try
If currentBird.Picture IsNot Nothing Then
Dim ms As New MemoryStream(currentBird.Picture)
picBird.Image = Image.FromStream(ms)
ms.Dispose()
Else
picBird.Image = Nothing
End If
Catch
picBird.Image = Nothing
End Try
End Sub
#End Region
此类中包含的下一个区域包含两个函数,用于控制鸟类数据列表的前向和后向导航。在这两种情况下,当前鸟类都通过调用 SaveCurrentBird
函数来保存。在本地保存当前鸟类后,将检查当前位置是否位于底部或顶部限制,如果可能,将递增或递减位置。更新当前位置后,将当前鸟类数据设置为更新位置处的鸟类数据,然后重新加载窗体。
#Region "Navigation"
''' <summary>
''' Navigate back to the previous record
''' if possible
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub tsbNavBack_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles tsbNavBack.Click
SaveCurrentBird()
If currentPosition <> 0 Then
currentPosition -= 1
currentBird = birds(currentPosition)
LoadCurrentBird()
End If
End Sub
''' <summary>
''' Navigate to the next bird
''' record if possible
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub tsbNavForward_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles tsbNavForward.Click
SaveCurrentBird()
If currentPosition < (birds.Count - 1) Then
currentPosition += 1
currentBird = birds(currentPosition)
LoadCurrentBird()
End If
End Sub
#End Region
此类代码的最后一个区域用于响应更改将窗体标记为脏。请注意,而不是使用值更改事件来设置脏窗体,而是使用了其他事件,例如文本框控件的按键事件,来提供更改的指示。原因是,如果打开一个鸟类数据文件并浏览列表,值会发生更改,并且窗体会被标记为脏,即使实际上没有发生更改。
#Region "Dirty Form"
''' <summary>
''' Dirty the form whenever the user
''' types into the bird name textbox
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub txtBirdName_KeyPress(ByVal sender As System.Object, _
ByVal e As
System.Windows.Forms.KeyPressEventArgs) _
Handles txtBirdName.KeyPress
dirtyForm = True
End Sub
''' <summary>
''' Dirty the form if the user clicks
''' on the gender combo box
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub cboGender_MouseClick(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.MouseEventArgs)
Handles cboGender.MouseClick
dirtyForm = True
End Sub
''' <summary>
''' Dirty the form whenever the user
''' types into the bird location textbox
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub txtLocation_KeyPress(ByVal sender As System.Object, _
ByVal e As
System.Windows.Forms.KeyPressEventArgs) _
Handles txtLocation.KeyPress
dirtyForm = True
End Sub
''' <summary>
''' Dirty the form whenever the user
''' types into the bird name textbox
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub txtBehavior_KeyPress(ByVal sender As System.Object, _
ByVal e As
System.Windows.Forms.KeyPressEventArgs) _
Handles txtBehavior.KeyPress
dirtyForm = True
End Sub
''' <summary>
''' Dirty the form if the user
''' opens the dtp control
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub dtpDate_CloseUp(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles dtpDate.CloseUp
dirtyForm = True
End Sub
''' <summary>
''' Dirty the form if the user
''' opens the dtp control
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub dtpTime_CloseUp(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles dtpTime.CloseUp
dirtyForm = True
End Sub
#End Region
End Class
以上是对应用程序主窗体中代码的讨论。
代码:列出所有鸟类窗体 (Form2.vb)
用于显示当前鸟类数据列表中所有鸟类的窗体非常简单。该窗体包含一个数据网格视图控件,用于显示鸟类数据列表。构造函数已修改为接受鸟类数据列表作为参数;构造函数将数据网格视图控件绑定到鸟类数据列表,并隐藏第一列(包含用于唯一标识记录的 Guid
)。
此类代码将全部提供。
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Public Class Form2
Public Sub New(ByVal bd As List(Of BirdData))
InitializeComponent()
' set the datasource of the grid
dataGridView1.DataSource = bd
' this is a guid to hide it
dataGridView1.Columns(0).Visible = False
End Sub
End Class
以上是 Form2
类的说明。
代码:查找鸟类窗体 (Form3.vb)
此窗体用于向用户提供当前鸟类数据列表中所有鸟类名称的列表。用户可以从列表中查看和选择鸟类名称,然后单击窗体的“查找”按钮;这将引发一个事件,主窗体将使用该事件将匹配的鸟类加载到窗体中。
该类以常规的默认库导入、命名空间声明和类声明开始。
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
''' <summary>
''' This form class displays a list of existing
''' bird names for the user to pick from; once
''' selected, an event will be raised with
''' the selected bird name passed as an
''' argument. The main form will listen
''' for an process this event to update
''' the display of the current bird to match
''' the search bird.
''' </summary>
Public Class Form3
在类声明之后,声明了一个委托和事件;这些用于在用户从窗体的列表中选择鸟类并单击窗体的“查找”按钮时通知主窗体。BirdNameUpdateEventArgs
被声明为一个单独的类;该类将用于包含选定的鸟类名称,并在引发 event
时将该信息提供给主窗体。
' add a delegate
Public Delegate Sub BirdNameUpdateHandler(ByVal sender As Object, ByVal e As
BirdNameUpdateEventArgs)
' and associated event to notify
' listeners when a bird name is
' picked from this form's bird
' name list
Public Event BirdNameUpdated As BirdNameUpdateHandler
构造函数已修改为接受鸟类数据列表作为参数;每当创建窗体实例时,构造函数都会遍历鸟类数据列表,并将每个鸟类名称添加到用于显示鸟类名称的 listbox
控件中。
''' <summary>
''' Pass current bird data list to the
''' constructor so that the form can
''' generate a list of bird names for
''' the user to choose from
''' </summary>
''' <param name="bd"></param>
''' <remarks></remarks>
Public Sub New(ByVal bd As List(Of BirdData))
InitializeComponent()
' iterate the bird data to add
' each bird name to the bird
' name list box control
For Each bird As BirdData In bd
listBox1.Items.Add(bird.BirdName)
Next
End Sub
查找按钮点击事件处理程序创建 event
参数的一个实例,并将 listbox
控件的选定项添加到事件参数中。设置后,将引发 event
,引发 event
将强制主窗体将选定鸟类的相关信息加载到窗体控件中。
''' <summary>
''' When the user clicks on the find button,
''' raise an event so the main form will display
''' the appropriate bird
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnFind_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnFind.Click
' populate the argument list with the bird name
Dim args As New BirdNameUpdateEventArgs(listBox1.SelectedItem.ToString())
' raise the event to pass the bird name back to the
' main form for processing
RaiseEvent BirdNameUpdated(Me, args)
End Sub
BirdNameUpdateEventArgs
类用于包含鸟类名称,并促进在触发鸟类名称更新事件时将鸟类名称传递给主窗体。此类可以扩展以包含更多属性。
''' <summary>
''' Container for the bird name update event arguments;
''' in this case there is only one argument, that being
''' the selected name of a bird from the bird list
''' </summary>
Public Class BirdNameUpdateEventArgs
Inherits System.EventArgs
Private mBirdName As String
' Class constructor
Public Sub New(ByVal sBirdName As String)
Me.mBirdName = sBirdName
End Sub
' Properties - Accessible by the listener
Public Property BirdName() As String
Get
Return mBirdName
End Get
Set(ByVal value As String)
mBirdName = value
End Set
End Property
End Class
以上是对查找窗体类(Form3.vb)的讨论。
摘要
本文介绍了一种在不实际使用数据库支持应用程序的情况下,在 WinForms 应用程序中持久化和管理数据的方法。这种方法可能在许多用户不与其他用户共享信息的应用程序中有用。即使示例展示了管理鸟类信息集合的方法,它也可以用于许多其他目的,例如维护飞蝇模式库,或者您喜欢的昆虫收藏、工具或设备库存等。
历史
- 2008年6月3日:初始版本