在 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。因此,您有一个单一的用户界面控件,其中注入了一个业务逻辑实例,以确定所执行处理的本质。