如何将事件处理程序添加到表适配器中的 RowUpdated 事件

发布于 2024-09-09 08:21:56 字数 386 浏览 2 评论 0原文

我有一个表适配器,我想在触发 RowUpdated 事件时执行一些操作。我不知道在哪里放置代码以将处理程序添加到事件。

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

创建 TableAdapter 时如何运行下面的代码?

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

I have a tableadapter and I want to do something when the RowUpdated event is fired. I can't figure out where to put the code to add the handler to the event.

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

How do I get the code below to run when the TableAdapter is created?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

薄凉少年不暖心 2024-09-16 08:21:57

我分两个阶段解决了这个问题。

一个。添加部分类并扩展表适配器

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();

I resolved this in 2 stages.

a. add partial class and extend table adapter

b. call a method in the beginning before using this adapter (say in main form after you create instance of it).

The code below is to resolve my particular issue with SQL CE to be able to update IDs on the table. However you can use the extended method to wrap the RowUpdated event and expose it to other classes (ie MyRowUpdated)

The extension

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();
        }
    }
}

The call in the main form:

        tableAdapter = new ScannedItemsTableAdapter();
        tableAdapter.Fill(ds.ScannedItems);
        tableAdapter.InitEvents();
拿命拼未来 2024-09-16 08:21:57

自从我上次使用这个东西以来已经有一段时间了,但是如果我没记错的话,你应该能够在你的部分类中重写 EndInit() 并添加初始化代码,比如在那里添加你的事件处理程序......

it has been a while since i last used this stuff, but if i remember correctly you should be able to override EndInit() in your partial class and add init code like adding your event handler there ...

拿命拼未来 2024-09-16 08:21:57

我有一个可能的替代方案。

虽然可以在 tableadapter 部分类中订阅 tableadapters 底层适配器,但我发现您无法轻松初始化它,而无需记住调用自己的初始化。

但是我发现我可以使用 tableadpater 直接从代码内订阅 tableadapters.adapter.rowupdated 事件,如下所示

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

“蜂鸣声是这样我可以添加一个断点进行测试”

因为无论如何我都必须订阅该事件我认为这更直观,不需要任何“记忆”

I have a possible alternative.

Whilst one can subscribe to the tableadapters underlying adapter in the tableadapter partial class I find you cannot easily initialise it without having to remember to call an initialisation of your own.

However I found that I can subscribe to a tableadapters.adapter.rowupdated event directly from within code using the tableadpater as below

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

"The beep is so I can add a breakpoint for testing"

Since I would have to subscribe to the event anyway I think this is more intuitive and doesnt require any "remembering"

月亮邮递员 2024-09-16 08:21:57

编辑:显然,下面建议的步骤都没有用。我将这个答案保留在这里纯粹是为了让其他试图回答它的人不会提出相同的建议。


您是否在设计器中创建TableAdapter?如果是这样,您是否可以直接单击属性页的“事件”部分,然后在 RowUpdated 条目中键入“OnRowUpdated”?

如果您在代码中显式创建适配器,只需自行添加调用即可。

或者,您的分部类是否有一个正在被调用的构造函数?同样,如果是这样,您可以在那里添加调用。

编辑:好的,所以大概这是在特定页面或表单中使用的 - 您可以在该页面/表单的 InitializeComponent 方法之后添加它吗?

EDIT: None of the steps suggested below are useful, apparently. I'm keeping this answer here purely so that anyone else trying to answer it doesn't come up with the same suggestions.


Are you creating the TableAdapter in the designer? If so, can you not just click on the Events part of the properties page, and type "OnRowUpdated" into the RowUpdated entry?

If you're creating the adapter explicitly in your code, just add the call yourself.

Alternatively, does your partial class have a constructor which is being called? Again, if so, you can add the call there.

EDIT: Okay, so presumably this is being used in a particular page or form - can you add it after the InitializeComponent method of that page/form?

眉黛浅 2024-09-16 08:21:57

http://windowsclient.net/learn/video.aspx?v=14625如果您观看此视频,您可以看到,您只需双击数据集设计器中的某些内容,事件就会生成并为您连接......但这仅适用于 VB 程序员:)) sux

http://windowsclient.net/learn/video.aspx?v=14625 if you look at this video you can see, that you just double click on something in the dataset designer and the event gets generated and wired up for you....but this works only for VB programmers :)) sux

机场等船 2024-09-16 08:21:57

覆盖你的 C# 类的 endinitin 并从那里触发事件处理程序

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

    }

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

    }

希望有帮助......

Override endinitin your C# class and fire event handler from there

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

    }

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

    }

Hope that helps................

樱&纷飞 2024-09-16 08:21:57
// 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;
  }
}
// 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;
  }
}
临走之时 2024-09-16 08:21:57

这是使用设计器的简单方法。右键单击数据集(.xsd 文件)并选择查看代码。就像表单一样,它不会打开设计器代码。它将打开您的代码。这是您的代码:

namespace TimeTrack.TimeTrackDataSetTableAdapters
{
    public partial class TimeSlipsTableAdapter
    {
        public void CustomSetup()
        {
            Adapter.RowUpdated += Adapter_RowUpdated;
        }

        private void Adapter_RowUpdated(object sender, OleDbRowUpdatedEventArgs e)
        {
            // whatever you want to do when RowUpdated fires
        }
    }
}

在您的表单中,不要忘记

    public TimeEntry()
    {
        InitializeComponent();
        timeSlipsTableAdapter.CustomSetup();

Here's an easy way to do it, using the Designer. Right-click on the dataset (the .xsd file) and select View Code. Just like with a form, it's not going to open the designer code. It's going to open your code. Here's your code:

namespace TimeTrack.TimeTrackDataSetTableAdapters
{
    public partial class TimeSlipsTableAdapter
    {
        public void CustomSetup()
        {
            Adapter.RowUpdated += Adapter_RowUpdated;
        }

        private void Adapter_RowUpdated(object sender, OleDbRowUpdatedEventArgs e)
        {
            // whatever you want to do when RowUpdated fires
        }
    }
}

In your form, don't forget to

    public TimeEntry()
    {
        InitializeComponent();
        timeSlipsTableAdapter.CustomSetup();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文