2013-08-17 27 views
1

我有一個窗體,我必須在其中填充DataGrid。此DataGrid的源來自另一個類。在DataTable的人口增加事件

我需要填充DataGrid通過Raising事件在那個類中,我得到Datatable。

Imports System.IO 

Public Class ExcelReader 

    Private WithEvents tmrRead As New Timer 

    Dim fullpath As String = "" 

    Public Sub ExcelReader() 
     tmrRead.Interval = 2000 
     tmrRead.Start() 
    End Sub 


    Public Sub TimerTick(ByVal sender As Object, ByVal e As System.EventArgs) Handles tmrRead.Tick 
     Dim DT As New DataTable 

     Dim path As String = Directory.GetParent(Directory.GetParent(Directory.GetCurrentDirectory).ToString).ToString + "\ExcelHotReader\" 

    Dim file1 As String() = System.IO.Directory.GetFiles(path, "*.xls") 
    Dim file2 As String() = System.IO.Directory.GetFiles(path, "*.xlsx") 
    If file1.Count <> 0 Or file2.Count <> 0 Then 
     tmrRead.Stop() 
    End If 

     If file1.Count <> 0 Then 
      fullpath = file1(0).ToString 
     End If 

     If file2.Count <> 0 Then 
      fullpath = file2(0).ToString 
     End If 

     Dim DT As New DataTable 
     Dim cn As System.Data.OleDb.OleDbConnection 
     Dim cmd As System.Data.OleDb.OleDbDataAdapter 
     cn = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;" & "data source=" & fullpath & ";Extended Properties=Excel 8.0;") 

     cmd = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", cn) 
     cn.Open() 
     cmd.Fill(DT) 
     cn.Close() 

    End Sub 
End Class 

在cn.Close()之後,應該用Datatable引發事件。此事件需要通過表單捕獲以填充DataGrid。

+0

如果你想支持「xls」和「xlsx」,你需要ACE.12.0 oledb provider而不是Jet.4.0 – Steve

+0

如果你想調用一個函數在cn.Close()之後,爲什麼不直接調用它?事件與具有「動態行爲」的控件相關聯,否則將不會被跟蹤。但是你的cn.Close()是非常靜態的:它寫在你的代碼行中;因此直接調用此行之後的給定方法沒有任何困難。 – varocarbas

回答

2

添加事件的聲明ExcelReader類中,並使用的RaiseEvent

Public Class ExcelReader 
    Public Event DataTableLoaded(ByVal dt As DataTable) 
    ....... 

     Using cn = New System.Data.OleDb.OleDbConnection("provider=Microsoft.ACE.12.0;.......") 
     Using cmd = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", cn) 
      cn.Open() 
      cmd.Fill(DT) 
      RaiseEvent DataTableLoaded(DT) 
     End Using 
     End Using 
    .... 
End Class 

然後調用代碼聲明(全局)的ExcelReader類的實例,用關鍵字在你的代碼的最後叫它WITHEVENTS

Public Dim WithEvents readerTableFromExcel = New ExcelReader() 

最後的是處理該事件(事件接收器)

Public Sub DataTableFromExcel(ByVal dt As System.Data.DataTable) _ 
      Handles readerTableFromExcel.DataTableLoaded 
    MsgBox("Table loaded") 
End Sub 
的方法的聲明

最後一點,我會用不同的方法來打開Excel文件的讀取(例如BackgroundWorker類比TimerTick事件似乎更合適)

如果您需要加深對事件的知識, this article似乎是一個很好的總結知道什麼是重要的

+0

+1,因爲您的答案非常詳細,併爲OP的問題提供了一個優雅的解決方案。但是我並沒有在這裏看到使事情複雜化的動機:在cn.Close()之後簡單地調用所需函數而不涉及事件的問題有什麼問題? – varocarbas

+0

@varocarbas我不知道。我認爲只有OP可以迴應你的問題。但是,也許,看到它使用TimerTick事件,可能他不希望它的GUI在加載表時被阻塞。 – Steve

+0

這工作.... –