Meine Anwendung enthält mehrere Formulare, die aus einem stark typisierten Datagridview, einer stark typisierten Bindungsquelle und einem stark typisierten Tabellenadapter bestehen.Wie kann ich Ereignisse an stark typisierte Datasets verschiedener Typen binden?
Ich verwende in jedem Formular einen Code, um die Datenbank zu aktualisieren, wenn der Benutzer die aktuelle Zeile verlässt, den Fokus vom Datagrid oder vom Formular verschiebt oder das Formular schließt.
Dieser Code ist in jedem Fall gleich, also möchte ich eine Unterklasse der Form machen, von der alle diese Formen erben können.
Aber die stark typisierten Datenobjekte erben alle von der Komponente, die die Ereignisse, an die ich binden will, oder die Methoden, die ich aufrufen möchte, nicht offen legen.
Der einzige Weg, ich, um Zugang zu den Ereignissen sehen kann, ist zu verwenden: Type(string Name).GetEvent(string EventName).AddEventHandler(object Target,Delegate Handler)
Ebenso mag ich die Update-Methode der stark typisierten Tabellenadapter nennen und Type(string Name).GetMethod(String name, Type[] params).Invoke(object target, object[] params)
verwenden.
Es funktioniert in Ordnung, aber es scheint sehr schwer zu händeln. Gibt es einen besseren Weg?
Hier ist mein Code für die Hauptklasse:
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();
}
}
}
Und hier ist eine (teilweise) Form, die es implementiert:
Diese demontrastespublic 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;
}
}