(强制性的初学警报!我不能保证我会理解你告诉我的一切。)
我有一个程序使用List<T>
自定义类CheckOrderLine
来填充DataGridView
到BindingSource
。在dataGrid
控件内,我提供了将记录“拆分”成多行以进行拼版的功能。我在解决这个过程的过程中遇到了麻烦。
我需要能够在dataGrid
中进行选择,从第一个选定的行开始,然后遍历选择中的每个CheckOrderLine
并将它们与第一行进行比较。
如果它们全部匹配,我需要将第一个记录中的数量更改为所有选定行的总和,然后删除多余的行。
这是我到目前为止自己制定的一段摘录:
int index = 1;
while (index < rowToJoin)
{
_bs.RaiseListChangedEvents = false;
int first = _bs.Position;
int second = first++;
CheckOrderLine current = (CheckOrderLine)_bs[first];
CheckOrderLine next = (CheckOrderLine)_bs[second];
if (current.OrderNumber == next.OrderNumber)
{
_bs.RemoveAt(second);
}
else
{
MessageBox.Show("You must select at least two matching rows to join.");
return;
}
_bs.RaiseListChangedEvents = true;
_bs.ResetBindings(false);
index++;
}
仅当我从下往上选择并且仅基于OrderNumber时才有效。为了防止意外,我真的需要检查两行之间的所有字段。能够在任何方向选择都是奖励。
编辑:我认为我原本不够清楚。OrderNumber
。current.OrderNumber == next.OrderNumber
以外的两行?我知道我可以将所有字段添加到if
语句中,但我更愿意让它更具可重用性。答案 0 :(得分:1)
仅当您从下往上选择时它才起作用的原因是BindingSource.Current
指向最后选择的项目,因此如果您从上到下选择,则您将与未选择的项目进行比较。
您似乎还有一个错误导致first
和second
被撤销。当您可能不想使用时,您正在使用后缀增量操作。
我们说_bs.Position
是5;
int first = _bs.Position; // first is now 5
int second = first++; // postfix increment: second is now 5, first is now 6
正如documentation所说,
操作的结果是操作数之前的值 已增加
所以你真的这样做了:
second = first;
first = first + 1;
看起来你只是想这样做:
second = first + 1;
它可能在这种情况下没有任何区别,但它使代码相当混乱。
有许多方法可以解决您的问题。这可能是一种更直接,更容易理解的方式:
int count = dgv.SelectedRows.Count;
// DataGridView.SelectedRows is reverse order, so the first selected item is the last item in the list
var firstSelected = dgv.SelectedRows[count - 1].DataBoundItem as CheckOrderLine;
int firstOrderNumber = firstSelected.OrderNumber;
// starting at second-last item (second selected row)
for (int i = count - 2; i >= 0; i--)
{
var row = dgv.SelectedRows[i];
var item = row.DataBoundItem as CheckOrderLine;
if (item.OrderNumber == firstOrderNumber)
dgv.Rows.Remove(row);
}
为了简单起见,我省略了更新剩余的行以及任何错误检查。
请注意,即使匹配的行不连续,这也会起作用。这取决于你是否允许。