My application contains several forms which consist of a strongly typed datagridview, a strongly typed bindingsource, and a strongly typed table adapter.
I am using some code in each form to update the database whenever the user leaves the current row, shifts focus away from the datagrid or the form, or closes the form.
This code is the same in each case, so I want to make a subclass of form, from which all of these forms can inherit.
But the strongly typed data objects all inherit from component, which doesn't expose the events I want to bind to or the methods I want to invoke.
The only way I can see of gaining access to the events is to use: Type(string Name).GetEvent(string EventName).AddEventHandler(object Target,Delegate Handler)
Similarly, I want to call the Update method of the strongly typed table adapter, and am using Type(string Name).GetMethod(String name, Type[] params).Invoke(object target, object[] params)
.
It works ok, but it seems very heavy handed. Is there a better way?
Here is my code for the main class:
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();
}
}
}
And here is a (partial) form which implements it:
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;
}
}