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

时间:2009-05-26 14:20:15

标签: c# reflection inheritance strongly-typed-dataset

我的应用程序包含几种形式,包括强类型数据网格视图,强类型绑定源和强类型表适配器。

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

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

但强类型数据对象都是从组件继承的,它不公开我想要绑定的事件或我想要调用的方法。

我可以看到获取对事件的访问权限的唯一方法是使用:Type(string Name).GetEvent(string EventName).AddEventHandler(object Target,Delegate Handler)

同样,我想调用强类型表适配器的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;

    }

}

1 个答案:

答案 0 :(得分:0)

这样就可以为您的类型化数据集使用“MustInherit”基类,以便访问未曝光的属性。

将此设置为每个键入的TableAdapter的“BaseClass”,替换“System.ComponentModel.Component”。 通过使用“MustInherit / MustOverride”(C#中的“Abstract”),您可以获得无法达到的属性。

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

对于您设置为继承BaseClass的每个表适配器,必须覆盖所需的“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”即可确保其可用。