我是否需要委托来执行此操作

本文关键字:执行 操作 是否 | 更新日期: 2023-09-27 18:30:30

>我有一个应用程序,其中有许多DataGridView,这些视图显示来自类的多个实例的信息。 该类具有各种属性,我为每个属性都有一个 DataGridView。

简单来说,我希望用户能够更新 DataGridView 中的值,然后有一个例程来获取该数据并更新类。

可以很容易地做到这一点,但我认为必须有一种更简洁的方法,我根本不够聪明,无法找到自己!

目前的做法是,我有一个函数,该函数从与其中一个属性关联的 DataGridView 开始,处理数据以专门更新该属性。 然后我对下一个 DataGridView 执行相同的操作,依此类推。 每个 DataGridView 的代码几乎相同,除了要更新的属性的名称,以及用于确保将 DataGridViewCell 内容转换为属性的正确类型(Double 和 Int)的类型转换。

现在:我花了很多时间试图研究一种更简洁的方法:委托、带有抽象方法的包装类、泛型。 问题是我不知道要搜索什么,但我认为最好的选择是某种带有 Lambda 的委托来指向要更新的属性,并对该属性进行类型检查。 不幸的是,我不知道该怎么做,所以我甚至无法真正开始为它编写代码!

这是我的基本前提:

//Update Priorities
if (_PrioritiesGrid != null)
{
    for (int i = 0; i < _PrioritiesGrid.Rows.Count - 1; i++)        //Ignore last row - it is blank for user added rows.
    {
        DataGridViewRow priorityRow = _PrioritiesGrid.Rows[i];
        DateTime productionDay = Convert.ToDateTime(priorityRow.Cells[0].Value);
        if (!storedDates.Contains(productionDay)) storedDates.Add(productionDay);
        for (int j = 1; j < priorityRow.Cells.Count; j++)
        {
            Well well = (Well)_PrioritiesGrid.Columns[j].Tag;
            if (_WellList.ContainsValue(well))
            {
                well.SetPriority(productionDay, Convert.ToInt32(priorityRow.Cells[j].Value));
            }
        }
    }
}
//Update Potentials
if (_PotentialsGrid != null)
{
    for (int i = 0; i < _PotentialsGrid.Rows.Count - 1; i++)        //Ignore last row - it is blank for user added rows.
    {
        DataGridViewRow potentialsRow = _PotentialsGrid.Rows[i];
        DateTime productionDay = Convert.ToDateTime(potentialsRow.Cells[0].Value);
        if (!storedDates.Contains(productionDay)) storedDates.Add(productionDay);
        for (int j = 1; j < potentialsRow.Cells.Count; j++)
        {
            Well well = (Well)_PotentialsGrid.Columns[j].Tag;
            if (_WellList.ContainsValue(well))
            {
                well.SetPotential(productionDay, Convert.ToDouble(potentialsRow.Cells[j].Value));
            }
        }
    }
}

Well.SetPotential() 用来自 _PotentialsGrid 的数据填充 Well 类的实例;Well.SetPriority() 用来自 _PrioritiesGrid 的数据填充 Well 类的实例。

我正在设想某种委托功能,这意味着我可以去:

ProcessGrid(_PotentialsGrid, x=>x.SetPotentials()) and
ProcessGrid(_PrioritiesGrid, x=>x.SetPriorities()) 

事实上,SetPotentials和SetPriority都接受参数(我只有在实际开始读取网格数据时才得到参数)是一个额外的复杂性!

如果有人能为我指出正确的方向,那就太好了。

我是否需要委托来执行此操作

我认为与代表一起去是个好主意。请基于控制反转为此创建一个解决方案(或框架)。

在高级别上,您的函数(或框架函数)应该接受两个输入 -

  1. DataGridView(或更好的抽象) - 因此,您应该能够指定要跟踪的单元格更新。
  2. 委托 - 这将是在指定单元格的值更改时需要调用的操作。要读取的单元格以及如何处理读取值将是委托的一部分。

现在,每次单元格的值更改时,框架都有责任调用您传递的委托(从而反转控制)。委托知道要读取哪些单元格以及如何处理读取值。

如果有任何不清楚的地方,或者如果您想拥有某种工作代码,请给我写评论。


更新 1 .了解委托的示例用法是必需的。提供示例代码

我按照您的需要将代码放在一个函数中ProcessGrid

public void ProcessGrid(DataGridView gridView, Action<Well, DateTime, DataGridViewCell> operaiton)
        {
            if (gridView != null)
            {
                for (int i = 0; i < gridView.Rows.Count - 1; i++)        //Ignore last row - it is blank for user added rows.
                {
                    DataGridViewRow priorityRow = gridView.Rows[i];
                    DateTime productionDay = Convert.ToDateTime(priorityRow.Cells[0].Value);
                     if (!storedDates.Contains(productionDay)) storedDates.Add(productionDay);
                    for (int j = 1; j < priorityRow.Cells.Count; j++)
                    {
                        Well well = (Well)gridView.Columns[j].Tag;
                          if (_WellList.ContainsValue(well))
                        {
                           // This is where the delegate will fire.
                            operaiton(well, productionDay, priorityRow.Cells[j]);
                        }
                    }
                }
            }
        }

这就是你可以称之为ProcessGrid函数的方式。

ProcessGrid(_PrioritiesGrid, (well, productionDay, cell) => { well.SetPriority(productionDay, Convert.ToInt32(cell.Value));});
ProcessGrid(_PotentialsGrid, (well, productionDay, cell) => { well.SetPotential(productionDay, Convert.ToDouble(cell.Value));});

我还没有执行它,但我乐观地认为它会正常工作。如果您有任何问题或任何部分不清楚,请给我写评论。