7.1.6 处理单元格事件 

 

代码
Sub DataGridView1_CellValidating(ByVal sender As Object,
ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs
)
Handles DataGridView1.CellValidating
Debug.WriteLine(
"Cell Validating: " & e.RowIndex & ", " & e.ColumnIndex)
If e.ColumnIndex = 1 AndAlso
e.FormattedValue.ToString.Trim.Length
= 0 Then
e.Cancel
= True
End If
End Sub

 

 

  

7.1.7.5 使用DataGridViewImageColumn对象

 

 用上下文菜单向ImageCell中插入图像 

代码
    Dim currentPhotoCell As DataGridViewImageCell
    
Sub InsertPhotoFromFileToolStripMenuItem_Click(ByVal sender As Object, _
                                                   
ByVal e As EventArgs _
                                                   ) 
Handles InsertPhotoFromFileToolStripMenuItem.Click
        
Dim dlg As New OpenFileDialog
        dlg.Multiselect 
= False
        dlg.Filter 
= "GIF|*.gif|BMP|*.bmp|JPEG|*.jpg;*.jpeg|All Files|*.*"
        dlg.FilterIndex 
= 3
        dlg.Title 
= "select a photo to insert"
        
If dlg.ShowDialog <> Windows.Forms.DialogResult.OK Then Return
        
Dim bmp As New Bitmap(dlg.FileName)
        currentPhotoCell.Value 
= bmp
    
End Sub

  

为上下文菜单设置CurrentPhotoCell变量值

代码
    Sub EmployeesDataGridView_CellContextMenuStripNeeded(ByVal sender As Object, _
                                                         
ByVal e As DataGridViewCellContextMenuStripNeededEventArgs _
                                                         ) 
Handles EmployeesDataGridView.CellContextMenuStripNeeded
        
Dim dg As DataGridView = CType(sender, DataGridView)
        
If TypeOf dg.Columns(e.ColumnIndex) Is DataGridViewImageColumn Then
            currentPhotoCell 
= CType(dg.Rows(e.RowIndex).Cells(e.ColumnIndex), DataGridViewImageCell)
        
End If
    
End Sub

  

 将DataGridViewImageCell对象中的图像保存到文件中 

代码
Imports System.IO
Imports System.Drawing.Imaging

    
Private Sub SavePhotoToFileToolStripMenuItem_Click(ByVal sender As System.Object, _
                                                       
ByVal e As System.EventArgs _
                                                       ) 
Handles SavePhotoToFileToolStripMenuItem.Click
        
Const oleOffset As Integer = 78
        
Const oleTypeStart As Integer = 20
        
Const oleTypeLength As Integer = 12

        
Dim imageBytes As Byte() = CType(currentPhotoCell.Value, Byte())

        
If imageBytes Is Nothing Or imageBytes.Length = 0 Then Return

        
Dim dlg As New SaveFileDialog
        dlg.AddExtension 
= True
        dlg.Filter 
= "GIF|*.gif|BMP|*.bmp|JPEG|*.jpg;*.jpeg|All Files|*.*"
        dlg.FilterIndex 
= 2
        dlg.Title 
= "Enter a file name for this photo"
        dlg.FileName 
= "EmployeePhoto.bmp"

        
If dlg.ShowDialog <> Windows.Forms.DialogResult.OK Then Return

        
Dim tempStream As MemoryStream
        
Dim type As String = System.Text.Encoding.ASCII.GetString(imageBytes, oleTypeStart, oleTypeLength)
        
If type = "Bitmap Image" Then
            tempStream 
= New MemoryStream(imageBytes, oleOffset, imageBytes.Length - oleOffset)
        
Else
            tempStream 
= New MemoryStream(imageBytes, 0, imageBytes.Length)
        
End If

        
Dim bmp As New Bitmap(tempStream)
        bmp.Save(dlg.FileName, ParseImageFormat(dlg.FileName))
    
End Sub

    
Function ParseImageFormat(ByVal filename As StringAs ImageFormat
        
Dim ext As String = Path.GetExtension(filename).ToLower
        
Select Case ext
            
Case "bmp"
                
Return ImageFormat.Bmp
            
Case "jpg""jpeg"
                
Return ImageFormat.Jpeg
            
Case "gif"
                
Return ImageFormat.Gif
            
Case Else
                
Return ImageFormat.Bmp
        
End Select
        
Return Nothing
    
End Function

 

 7.1.9 实现Virtual模式

类Fruit的代码

代码
Public Class Fruit
    
Public Property Name() As String
        
Get
            
Return _name
        
End Get
        
Set(ByVal value As String)
            _name 
= value
        
End Set
    
End Property
    
Dim _name As String

    
Public Property Calories() As Decimal
        
Get
            
Return _calories
        
End Get
        
Set(ByVal value As Decimal)
            _calories 
= value
        
End Set
    
End Property
    
Dim _calories As Decimal

    
Public Property Carbs() As Decimal
        
Get
            
Return _carbs
        
End Get
        
Set(ByVal value As Decimal)
            _carbs 
= value
        
End Set
    
End Property
    
Dim _carbs As Decimal

    
Public Sub New(ByVal name As StringByVal calories As DecimalByVal carbs As Decimal)
        
Me.Name = name
        
Me.Calories = calories
        
Me.Carbs = carbs
    
End Sub
End Class

 

实现Virtual模式 

代码
Public Class Form1
    
Private fruitList As New List(Of Fruit)
    
Private rowInEdit As Integer = -1
    
Private fruitInEdit As Fruit = Nothing

    
Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        
With fruitList
            .Add(
New Fruit("Apple"4410.5))
            .Add(
New Fruit("Banana"10726))
            .Add(
New Fruit("Orange"358.5))
        
End With
        DataGridView1.RowCount 
= fruitList.Count + 1

    
End Sub

    
Sub DataGridView1_CellValueNeeded(ByVal sender As ObjectByVal e As DataGridViewCellValueEventArgs) Handles DataGridView1.CellValueNeeded
        
If e.RowIndex = DataGridView1.RowCount - 1 Then
            
Return
        
End If

        
Dim tmpFruit As Fruit = Nothing
        
If e.RowIndex = rowInEdit Then
            tmpFruit 
= Me.fruitInEdit
        
Else
            tmpFruit 
= fruitList(e.RowIndex)
        
End If

        
Select Case Me.DataGridView1.Columns(e.ColumnIndex).Name
            
Case "FruitName"
                e.Value 
= tmpFruit.Name
            
Case "Calories"
                e.Value 
= tmpFruit.Calories
            
Case "Carbs"
                e.Value 
= tmpFruit.Carbs
        
End Select
    
End Sub
End Class

 

向DataGridView对象添加新行 

代码
    Sub DataGridView1_NewRowNeeded(ByVal sender As ObjectByVal e As DataGridViewRowEventArgs) Handles DataGridView1.NewRowNeeded
        fruitInEdit 
= New Fruit(""00)
        rowInEdit 
= DataGridView1.Rows.Count - 1
    
End Sub

    
Sub DataGridView1_CellValuePushed(ByVal sender As ObjectByVal e As DataGridViewCellValueEventArgs) Handles DataGridView1.CellValuePushed
        
Dim tmpFruit As Fruit = Nothing
        
If e.RowIndex < fruitList.Count Then
            
If fruitInEdit Is Nothing Then
                
With fruitList(e.RowIndex)
                    fruitInEdit 
= New Fruit(.Name, .Calories, .Carbs)
                
End With
            
End If

            tmpFruit 
= fruitInEdit
            rowInEdit 
= e.RowIndex
        
Else
            tmpFruit 
= fruitInEdit
        
End If

        
Dim newValue As String = TryCast(e.Value, String)
        
Select Case DataGridView1.Columns(e.ColumnIndex).Name
            
Case "FruitName"
                tmpFruit.Name 
= newValue
            
Case "Calories"
                tmpFruit.Calories 
= Decimal.Parse(newValue)
            
Case "Carbs"
                tmpFruit.Carbs 
= Decimal.Parse(newValue)
        
End Select
    
End Sub

    
Sub DataGridView1_RowValidated(ByVal sender As ObjectByVal e As DataGridViewCellEventArgs) Handles DataGridView1.RowValidated
        
If e.RowIndex >= fruitList.Count And e.RowIndex <> DataGridView1.Rows.Count - 1 Then
            fruitList.Add(fruitInEdit)
            fruitInEdit 
= Nothing
            rowInEdit 
= -1
        
ElseIf Not fruitInEdit Is Nothing And e.RowIndex < fruitList.Count Then
            fruitList(e.RowIndex) 
= fruitInEdit
            fruitInEdit 
= Nothing
            rowInEdit 
= -1
        
Else
            fruitInEdit 
= Nothing
            rowInEdit 
= -1
        
End If
    
End Sub

  

添加删除行和取消取行编辑的功能

代码
    Sub DataGridView1_UserDeletingRow(ByVal sender As ObjectByVal e As DataGridViewRowCancelEventArgs) Handles DataGridView1.UserDeletingRow
        
If e.Row.Index < fruitList.Count Then
            fruitList.RemoveAt(e.Row.Index)
        
End If

        
If e.Row.Index = Me.rowInEdit Then
            rowInEdit 
= -1
            fruitInEdit 
= Nothing
        
End If
    
End Sub

    
Sub DataGridView1_CancelRowEdit(ByVal sender As ObjectByVal e As QuestionEventArgs) Handles DataGridView1.CancelRowEdit
        
If rowInEdit = DataGridView1.Rows.Count - 2 And rowInEdit = fruitList.Count Then
            fruitInEdit 
= New Fruit(""00)
        
Else
            fruitInEdit 
= Nothing
            rowInEdit 
= -1
        
End If
    
End Sub