我是否需要委托来执行此操作
本文关键字:执行 操作 是否 | 更新日期: 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都接受参数(我只有在实际开始读取网格数据时才得到参数)是一个额外的复杂性!
如果有人能为我指出正确的方向,那就太好了。
我认为与代表一起去是个好主意。请基于控制反转为此创建一个解决方案(或框架)。
在高级别上,您的函数(或框架函数)应该接受两个输入 -
- DataGridView(或更好的抽象) - 因此,您应该能够指定要跟踪的单元格更新。
- 委托 - 这将是在指定单元格的值更改时需要调用的操作。要读取的单元格以及如何处理读取值将是委托的一部分。
现在,每次单元格的值更改时,框架都有责任调用您传递的委托(从而反转控制)。委托知道要读取哪些单元格以及如何处理读取值。
如果有任何不清楚的地方,或者如果您想拥有某种工作代码,请给我写评论。
更新 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));});
我还没有执行它,但我乐观地认为它会正常工作。如果您有任何问题或任何部分不清楚,请给我写评论。