C# 如何将事件绑定到不同类型的强类型数据集?

C# 如何将事件绑定到不同类型的强类型数据集?,c#,reflection,inheritance,strongly-typed-dataset,C#,Reflection,Inheritance,Strongly Typed Dataset,我的应用程序包含几个表单,它们由强类型datagridview、强类型bindingsource和强类型表适配器组成 每当用户离开当前行、将焦点从datagrid或表单移开或关闭表单时,我都会在每个表单中使用一些代码来更新数据库 这段代码在每种情况下都是相同的,所以我想创建form的子类,所有这些表单都可以从中继承 但强类型数据对象都继承自组件,组件不公开要绑定的事件或要调用的方法 获取事件访问权限的唯一方法是使用:Type(string Name).GetEvent(string EventN

我的应用程序包含几个表单,它们由强类型datagridview、强类型bindingsource和强类型表适配器组成

每当用户离开当前行、将焦点从datagrid或表单移开或关闭表单时,我都会在每个表单中使用一些代码来更新数据库

这段代码在每种情况下都是相同的,所以我想创建form的子类,所有这些表单都可以从中继承

但强类型数据对象都继承自组件,组件不公开要绑定的事件或要调用的方法

获取事件访问权限的唯一方法是使用:
Type(string Name).GetEvent(string EventName).AddEventHandler(对象目标,委托处理程序)

类似地,我想调用强类型表适配器的Update方法,并使用
Type(string Name).GetMethod(string Name,Type[]params).Invoke(object target,object[]params)

它工作正常,但看起来很笨重。有更好的办法吗

以下是我的主类代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
using System.ComponentModel;

namespace MyApplication
{
    public class AutoSaveDataGridForm: Form
    {
        private DataRow PreviousRow;

        public Component Adapter
        {
            private get;
            set;
        }


        private Component dataGridView;
        public Component DataGridView
        {
            private get
            {
                return dataGridView;
            }
            set
            {
                dataGridView = value;
                Type t = dataGridView.GetType();
                t.GetEvent("Leave").AddEventHandler(dataGridView, new EventHandler(DataGridView_Leave));

            }
        }
        private Component bindingSource;
        public Component BindingSource
        {
            private get
            {
                return bindingSource;
            }
            set
            {
                bindingSource = value;
                Type t = bindingSource.GetType();
                t.GetEvent("PositionChanged").AddEventHandler(bindingSource, new EventHandler(BindingSource_PositionChanged));


            }
        }



        protected void Save()
        {
            if (PreviousRow != null && PreviousRow.RowState != DataRowState.Unchanged)
            {
                Type t = Adapter.GetType();
                t.GetMethod("Update", new Type[] { typeof(DataRow[]) }).Invoke(Adapter, new object[] { new DataRow[] { PreviousRow } });

            }

        }


        private void BindingSource_PositionChanged(object sender, EventArgs e)
        {
            BindingSource bindingSource = sender as BindingSource;
            DataRowView CurrentRowView = bindingSource.Current as DataRowView;
            DataRow CurrentRow = CurrentRowView.Row;
            if (PreviousRow != null && PreviousRow != CurrentRow)
            {
                Save();
            }
            PreviousRow = CurrentRow;

        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // AutoSaveDataGridForm
            // 
            this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.AutoSaveDataGridForm_FormClosed);
            this.Leave += new System.EventHandler(this.AutoSaveDataGridForm_Leave);
            this.ResumeLayout(false);

        }

        private void DataGridView_Leave(object sender, EventArgs e)
        {
            Save();
        }

        private void AutoSaveDataGridForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            Save();
        }

        private void AutoSaveDataGridForm_Leave(object sender, EventArgs e)
        {
            Save();
        }


    }
}
下面是实现它的(部分)表单:

    public partial class FileTypesInherited :AutoSaveDataGridForm
{
    public FileTypesInherited()
    {
        InitializeComponent();
    }

    private void FileTypesInherited_Load(object sender, EventArgs e)
    {
        // TODO: This line of code loads data into the 'sharedFoldersInformationV2DataSet.tblFileTypes' table. You can move, or remove it, as needed.
        this.tblFileTypesTableAdapter.Fill(this.sharedFoldersInformationV2DataSet.tblFileTypes);
        this.BindingSource = tblFileTypesBindingSource;
        this.Adapter = tblFileTypesTableAdapter;
        this.DataGridView = tblFileTypesDataGridView;

    }

}

这将演示如何为类型化数据集使用“MustInherit”基类来访问未公开的属性

将其设置为每个类型化TableAdapter的“基类”,替换为“System.ComponentModel.Component”。 通过使用“MustInherit/MustOverride”(“C#中的“抽象”),您可以获得其他方法无法访问的属性

Public MustInherit Class SuperTableAdapter
    Inherits System.ComponentModel.Component

    Public MustOverride ReadOnly Property MyCommandCollection As Data.SqlClient.SqlCommand()

    Public Sub New()
        MyBase.New()
        'With the command collection exposed, you can replace it with your own.  You can do the same for events.'

        For i = 0 To MyCommandCollection.Length - 1
             Dim myspecialCommand As New Data.SqlClient.SqlCommand()
            MyCommandCollection(i) = myspecialCommand
        Next
    End Sub
End Class
对于设置为继承基类的每个表适配器,必须重写所需的“MustOverride”属性。没有它,它就无法编译。如果添加代码但未设置TableAdapter基类,则它也不会编译。这是件好事;它确保你做对了

Namespace DataSet1TableAdapters
    Partial Public Class Table1TableAdapter
        Public Overrides ReadOnly Property MyCommandCollection As System.Data.SqlClient.SqlCommand()
            Get
                Return Me.CommandCollection
            End Get
        End Property
    End Class

    Partial Public Class Table2TableAdapter
        Public Overrides ReadOnly Property MyCommandCollection As System.Data.SqlClient.SqlCommand()
            Get
                Return Me.CommandCollection
            End Get
        End Property
    End Class
End Namespace
现在,您可以在SuperTableAdapter中放入各种特殊代码。如果您需要访问未公开的内容,只需使用“MustOverride”来保证它可用