Мое приложение содержит несколько форм, которые состоят из строго типизированной таблицы данных, строго типизированного источника привязок и адаптера таблицы со строгой типизацией.
Я использую некоторый код в каждой форме для обновления базы данных всякий раз, когда пользователь покидает текущую строку, смещает фокус с сетки данных или формы или закрывает форму.
Этот код одинаков в каждом случае, поэтому я хочу создать подкласс формы, от которого могут наследоваться все эти формы.
Но строго типизированные объекты данных наследуются от компонента, который не отображает события, к которым я хочу привязаться, или методы, которые я хочу вызвать.
Единственный способ получить доступ к событиям - это использовать: 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;
}
}