2010-07-14 47 views
7

我有一個tableadapter,並且我想在RowUpdated事件觸發時執行某些操作。我無法弄清楚把代碼添加到事件處理程序的位置。如何添加事件處理程序到表格適配器中的RowUpdated事件

public partial class MyTableAdapter 
{ 
    void OnRowUpdated(object sender, System.Data.Odbc.OdbcRowUpdatedEventArgs e) 
    { 
    } 
} 

如何在TableAdapter創建時運行下面的代碼?

Adapter.RowUpdated += 
        new System.Data.Odbc.OdbcRowUpdatedEventHandler(OnRowUpdated); 
+0

如果你有機會把它放在適配器的創建後,我會把它那裏如果你有'InitializeComponent'方法它在容器類的構造函數中爲你做初始化,並在'InitializeComponent'調用之後立即執行代碼。 – Andreas 2010-07-14 06:46:36

+0

我在這個問題上付出了一定的代價,因爲從.NET 1.1開始,我經常遇到這樣一個問題,我覺得在實例化它之後,必須有更好的解決方案,而不是竊聽表適配器。 – 2011-04-18 13:20:33

+0

答案中提供的解決方案實用而且技術完善。 – 2013-01-23 13:16:46

回答

3

我在第2個階段解決了這個。

a。添加部分類和擴展表適配器

b。在使用這個適配器之前在開始時調用一個方法(比如在創建它的實例之後在主窗體中)。

下面的代碼是解決我與SQL CE的特定問題,以便能夠更新表上的ID。但是,您可以使用擴展方法來包裝RowUpdated事件,並暴露在其他類(即MyRowUpdated)

擴展

public partial class ScannedItemsTableAdapter 
{ 
    public void InitEvents() 
    { 
     this._adapter.RowUpdated += _adapter_RowUpdated; 
    } 

    void _adapter_RowUpdated(object sender, SqlCeRowUpdatedEventArgs e) 
    { 
     if (e.Status == UpdateStatus.Continue && 
      e.StatementType == StatementType.Insert) 
     { 
      var pk = e.Row.Table.PrimaryKey; 
      pk[0].ReadOnly = false; 

      SqlCeCommand cmd = new SqlCeCommand("SELECT @@IDENTITY", 
       e.Command.Connection, e.Command.Transaction); 

      object id = (decimal)cmd.ExecuteScalar(); 

      e.Row[pk[0]] = Convert.ToInt32(id); 
      e.Row.AcceptChanges(); 
     } 
    } 
} 

在主窗體調用:

 tableAdapter = new ScannedItemsTableAdapter(); 
     tableAdapter.Fill(ds.ScannedItems); 
     tableAdapter.InitEvents(); 
+0

這就是我已經解決了這個問題的方法,但是當創建表適配器時,我正在尋找一種方法來連接表適配器類中的事件。 – Simon 2013-01-23 12:15:22

+0

謝謝。我也是這樣結束的。對於將來的讀者,確保你調用了'InitEvents()'之後,你的適配器對象已經被初始化,而不是在你的表單的構造函數中。 – dotNET 2013-06-06 02:56:39

0

編輯:顯然,下面建議的步驟都不是很有用。我在這裏單純地保留這個答案,以便其他人試圖回答它並不會提出相同的建議。


您是在設計器中創建TableAdapter嗎?如果是這樣,您是否可以不單擊屬性頁面的「事件」部分,然後在RowUpdated條目中鍵入「OnRowUpdated」?

如果您要在代碼中明確創建適配器,請自行添加該調用。

或者,您的部分類是否有一個被調用的構造函數?同樣,如果是這樣,您可以在那裏添加呼叫。

編輯:好吧,大概這是用於特定的頁面或窗體 - 你可以在頁面/表單的InitializeComponent方法後添加它?

+1

我正在使用設計器來創建帶有數據表和表格適配器的類型化數據集。我可以看到沒有屬性頁面的事件部分。 由於設計師已經創建了一個構造函數,我不能在分部類中添加它。 – Simon 2010-07-14 06:54:03

+0

@Simon:我指的是設計師在哪裏使用適配器 - 即形式/無論你在哪裏包括它。不是數據集設計者。 – 2010-07-14 07:03:57

+1

我可以公開OnRowUpdated處理程序並在表單上使用以下代碼: MyTableAdapter myAdapter = new MyTableAdapter(); myAdapter.Adapter.RowUpdated + = new System.Data.Odbc.OdbcRowUpdatedEventHandler(myAdapter.OnRowUpdated); 但是我更喜歡在適配器的partial類中這樣做,以便數據集的用戶在每次創建適配器實例時不必記得添加此代碼。 – Simon 2010-07-14 07:19:59

0

http://windowsclient.net/learn/video.aspx?v=14625如果你看看這個視頻,你可以看到,你只需雙擊數據集設計器中的某些東西,事件就會生成並連線起來......但這隻適用於VB程序員:)) SUX

+0

更具體@ 5:00分鐘Beth double單擊數據表並獲取xxRowChanging事件 – 2011-01-10 23:48:38

0

它已經有一段時間我上次用過這東西,但如果我沒記錯的話,你應該能夠覆蓋EndInit()在你的部分類,並添加如添加事件處理程序存在初始化代碼...

0

覆蓋最終你的C#類和火災事件處理程序

public override void EndInit() 
    { 
     base.EndInit(); 
     Adapter.RowUpdated += 
        new System.Data.Odbc.OdbcRowUpdatedEventHandler(OnRowUpdated); 

    } 

    void OnRowUpdated(object sender, System.Data.Odbc.OdbcRowUpdatedEventArgs e) 
    { 

    } 

希望幫助................

+0

TableAdapter類不允許您重寫EndInit(沒有找到合適的重寫方法)。 DataTable部分類允許您覆蓋EndInit,但我無法看到如何從DataTable訪問相關的TableAdapter。 – Simon 2011-04-27 06:58:53

0
// Assumes that connection is a valid SqlConnection object. 

SqlDataAdapter custAdapter = new SqlDataAdapter(
    "SELECT CustomerID, CompanyName FROM Customers", connection); 

// Add handlers. 

custAdapter.RowUpdating += new SqlRowUpdatingEventHandler(OnRowUpdating); 
custAdapter.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated); 

// Set DataAdapter command properties, fill DataSet, modify DataSet. 


custAdapter.Update(custDS, "Customers"); 

// Remove handlers. 

custAdapter.RowUpdating -= new SqlRowUpdatingEventHandler(OnRowUpdating); 
custAdapter.RowUpdated -= new SqlRowUpdatedEventHandler(OnRowUpdated); 

protected static void OnRowUpdating(
    object sender, SqlRowUpdatingEventArgs args) 
{ 
    if (args.StatementType == StatementType.Delete) 
    { 
    System.IO.TextWriter tw = System.IO.File.AppendText("Deletes.log"); 
    tw.WriteLine(
     "{0}: Customer {1} Deleted.", DateTime.Now, 
     args.Row["CustomerID", DataRowVersion.Original]); 
    tw.Close(); 
    } 
} 

protected static void OnRowUpdated(
    object sender, SqlRowUpdatedEventArgs args) 
{ 
    if (args.Status == UpdateStatus.ErrorsOccurred) 
    { 
    args.Row.RowError = args.Errors.Message; 

    args.Status = UpdateStatus.SkipCurrentRow; 
    } 
} 
+0

當他們伴隨着一些*解釋*,而不是簡單的代碼牆時,答案會更好。 – 2011-04-22 12:58:11

1

我有一個可能的選擇。

雖然一個可以訂閱基本在TableAdapter的部分類,我覺得你不能輕易地初始化它的適配器中的TableAdapter,而不必記住打電話給自己的初始化。

不過,我發現,我可以直接在代碼中使用tableadpater如下

AddHandler Me.TA_Case_Transactions.Adapter.RowUpdated, AddressOf Transaction_Row_Written 

    Private Sub Transaction_Row_Written(p_Sender As Object, p_E As SqlRowUpdatedEventArgs) 
     beep 
    End Sub 

訂閱tableadapters.adapter.rowupdated事件「的提示音是這樣我就可以添加一個斷點測試」

由於我必須訂閱事件,我認爲這是更直觀,不需要任何「記憶」

相關問題