在 WinForms 中正确使用 OOP
Using OOP in WinForms Correctly
我有 3 个 WinForm 控件,每个控件都具有相同的功能...
a) 将数据加载到数据网格视图
b) 批准数据
c) 运行 报告
我想在构建时考虑到 OOP。我开始学习 OOP 并将其应用到我的应用程序中。
1) 创建包含以下抽象方法的抽象控件 class...
- LoadData()
- ApproveData()
- RunReport()
和属性...
- UserID
- PeriodRunDate
2) 为3个控件中的每一个创建一个控件subclass并实现抽象class
3) 为每个方法添加自定义代码
4) 在客户端 WinForm 中加载这些子class 控件,并从客户端窗体调用方法。
以下是我迄今为止的代码。我在正确的道路上吗?如何使用客户端表单和子classes 中的抽象属性?
// Abstract Class Control code...
public partial class AbstractUserControl : UserControl
{
protected abstract string userID { get; }
protected abstract string periodRunDate { get; }
protected abstract void LoadData(DoWorkEventArgs doWorkEventArgs);
protected abstract void DataLoaded(RunWorkerCompletedEventArgs runWorkerCompletedEventArgs);
protected abstract void ApproveData();
protected abstract void RunReport();
public void LoadDataButton_Click(object sender, System.EventArgs eventArgs)
{
this._uiLoadDataBackgroundWorker.RunWorkerAsync();
}
private void _uiLoadDataBackgroundWorker_DoWork(object sender, DoWorkEventArgs doWorkEventArgs)
{
this.LoadData(doWorkEventArgs);
}
private void _uiLoadDataBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
{
this.DataLoaded(runWorkerCompletedEventArgs);
}
}
// first subclass usercontrol
public partial class DetailsUserControl : UserControl
{
private DataSet.DataTable DataTable;
protected override void LoadData(DoWorkEventArgs doWorkEventArgs)
{
DataSetTableAdapters.DataTableAdapter
dataTableAdapter = new DataSetTableAdapters.DataTableAdapter();
this.DataTable = new DataSet.DataTable();
DataTableAdapter.FillData(this.DataTable, userID, periodRunDate);
}
protected override void DataLoaded(RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
{
this.bindingSource.DataSource = this.DataTable;
}
protected override void ApproveData()
{
// check each row ticked in the datagridview
// and update record in database
}
}
// Client WinForm that loads UserControl(s); Uses RunButton click event
// to call LoadButton Click in subclass controls...
private AbstractUserControl abstractUserControl;
private void RunButton_Click(object sender, EventArgs e)
{
// bind to load data button click event in abstract class
this.LoadDataButton.Click += this.abstractUserControl.LoadDataButton_Click;
}
虽然继承基础 class 的方法非常好,但不幸的是,它不能很好地与 Windows 表单设计器配合使用。因此,如果您打算双击 class 文件,然后使用表单设计器进行拖放等操作,则无法正常工作。相反,我会推荐以下替代模式。
创建一个标准的用户控件,然后您可以像往常一样使用窗体设计器对其进行设计。这个控件将用于您拥有的所有三个相关场景。然后创建一个基础 class,其中包含三个派生的 class 实体,它们实现了您需要的业务逻辑。
向 UserControl 添加一个 属性 或方法,使您可以将业务逻辑实例注入到控件中。控件然后调用实例的公开摘要 methods/properties。因此,您有一个单一的用户界面控件,其中注入了一个业务逻辑实例,以确定所执行处理的本质。
我有 3 个 WinForm 控件,每个控件都具有相同的功能...
a) 将数据加载到数据网格视图
b) 批准数据
c) 运行 报告
我想在构建时考虑到 OOP。我开始学习 OOP 并将其应用到我的应用程序中。
1) 创建包含以下抽象方法的抽象控件 class...
- LoadData()
- ApproveData()
- RunReport()
和属性...
- UserID
- PeriodRunDate
2) 为3个控件中的每一个创建一个控件subclass并实现抽象class
3) 为每个方法添加自定义代码
4) 在客户端 WinForm 中加载这些子class 控件,并从客户端窗体调用方法。
以下是我迄今为止的代码。我在正确的道路上吗?如何使用客户端表单和子classes 中的抽象属性?
// Abstract Class Control code...
public partial class AbstractUserControl : UserControl
{
protected abstract string userID { get; }
protected abstract string periodRunDate { get; }
protected abstract void LoadData(DoWorkEventArgs doWorkEventArgs);
protected abstract void DataLoaded(RunWorkerCompletedEventArgs runWorkerCompletedEventArgs);
protected abstract void ApproveData();
protected abstract void RunReport();
public void LoadDataButton_Click(object sender, System.EventArgs eventArgs)
{
this._uiLoadDataBackgroundWorker.RunWorkerAsync();
}
private void _uiLoadDataBackgroundWorker_DoWork(object sender, DoWorkEventArgs doWorkEventArgs)
{
this.LoadData(doWorkEventArgs);
}
private void _uiLoadDataBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
{
this.DataLoaded(runWorkerCompletedEventArgs);
}
}
// first subclass usercontrol
public partial class DetailsUserControl : UserControl
{
private DataSet.DataTable DataTable;
protected override void LoadData(DoWorkEventArgs doWorkEventArgs)
{
DataSetTableAdapters.DataTableAdapter
dataTableAdapter = new DataSetTableAdapters.DataTableAdapter();
this.DataTable = new DataSet.DataTable();
DataTableAdapter.FillData(this.DataTable, userID, periodRunDate);
}
protected override void DataLoaded(RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
{
this.bindingSource.DataSource = this.DataTable;
}
protected override void ApproveData()
{
// check each row ticked in the datagridview
// and update record in database
}
}
// Client WinForm that loads UserControl(s); Uses RunButton click event
// to call LoadButton Click in subclass controls...
private AbstractUserControl abstractUserControl;
private void RunButton_Click(object sender, EventArgs e)
{
// bind to load data button click event in abstract class
this.LoadDataButton.Click += this.abstractUserControl.LoadDataButton_Click;
}
虽然继承基础 class 的方法非常好,但不幸的是,它不能很好地与 Windows 表单设计器配合使用。因此,如果您打算双击 class 文件,然后使用表单设计器进行拖放等操作,则无法正常工作。相反,我会推荐以下替代模式。
创建一个标准的用户控件,然后您可以像往常一样使用窗体设计器对其进行设计。这个控件将用于您拥有的所有三个相关场景。然后创建一个基础 class,其中包含三个派生的 class 实体,它们实现了您需要的业务逻辑。
向 UserControl 添加一个 属性 或方法,使您可以将业务逻辑实例注入到控件中。控件然后调用实例的公开摘要 methods/properties。因此,您有一个单一的用户界面控件,其中注入了一个业务逻辑实例,以确定所执行处理的本质。