我有一个应用程序,其中有许多DataGridViews,它显示来自多个类实例的信息。该类有各种属性,每个都有一个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中的Data填充Well Class的实例。
我正在设想某种委托功能,这意味着我可以去:
ProcessGrid(_PotentialsGrid, x=>x.SetPotentials()) and
ProcessGrid(_PrioritiesGrid, x=>x.SetPriorities())
SetPotentials和SetPriorities都采用参数(我在实际开始阅读网格数据时才会得到)这一事实是一个额外的复杂因素!
如果有人能指出我正确的方向,那就太好了。
答案 0 :(得分:1)
我认为与代表们合作是一个好主意。 请根据控制反转为此创建解决方案(或框架)。
在较高级别,您的功能(或框架功能)应该采用两个输入 -
现在,每当单元格的值发生变化时,框架都有责任调用您传递的委托(从而反转控制权)。 代表知道要读取哪些单元格&amp;如何处理读取值。
如果有任何不清楚的地方或者您想要某种工作代码,请给我发表评论。
我根据您的需要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));});
我没有执行它,但我乐观地认为它会正常工作。如果您有任何问题或任何部分不清楚,请写信给我。