【发布时间】:2015-06-11 15:55:47
【问题描述】:
我有一个绑定到DataTable 的DataGridView (dgvVolReport)。表中有一个名为"group" 的列(DataGridView 上的colGroup)。我正在尝试创建一个按钮,可以将所有选定的行组合在一起(即分配相同的组号)。
我有分配组号并正确编辑其他组号的逻辑,并且每行的新组存储在名为groupNumbersAll 的List<int> 中。
然后我将这些号码转移到DataGridView,如下所示:
for (int r = 0; r < groupNumbersAll.Count; r++)
{
dgvVolReport.Rows[r].Cells["colGroup"].Value = groupNumbersAll[r];
}
// A breakpoint is set on this line (i.e. values below are BEFORE this line has been run
dgvVolReport.Sort(colGroup, ListSortDirection.Ascending);
不知何故,这似乎改变了行顺序或将数字分配给错误的行。
我已经在那个循环之后进行了调试,groupNumbersAll 的内容是正确的:
请注意,这两个固定的“六”对应于两个选定的行(之前是五行)。现在,colGroup 列的内容如下所示:
您可以从6 行看到它们不匹配。为什么他们不匹配?为什么?
但更奇怪的是,如果我注释掉最后一行 (dgvVolReport.Sort(colGroup, ListSortDirection.Ascending);),它甚至还没有运行,因为那是断点所在的位置,然后它们突然匹配了!!!有谁知道这里发生了什么?
顺便说一句,我也尝试过解除绑定,然后重新绑定我认为有一段时间的 DataSource,但现在我发现它没有。
以下是请求的组按钮的完整代码(来自按钮单击)(注意最终工作代码为here):
private void btnGroup_Click(object sender, EventArgs e)
{
//dgvVolReport.CommitEdit(DataGridViewDataErrorContexts.Commit);
List<int> groupNumbersAll = new List<int>();
List<int> groupNumbersNotSelected = new List<int>();
List<int> groupNumbersSelected = new List<int>();
List<int> rowNumbersSelected = new List<int>();
List<int> groupNumbersOfEntirelySelectedGroups = new List<int>();
// Populate groups (All, Selected and NotSelected)
foreach (DataGridViewRow row in dgvVolReport.Rows)
{
groupNumbersAll.Add(Convert.ToInt16(row.Cells["colGroup"].Value));
if (row.Selected)
{
groupNumbersSelected.Add(Convert.ToInt16(row.Cells["colGroup"].Value));
rowNumbersSelected.Add(row.Index);
}
else
{
groupNumbersNotSelected.Add(Convert.ToInt16(row.Cells["colGroup"].Value));
}
}
int smallestSelectedGroupNumber = groupNumbersSelected.Min();
int newGroupNumber = smallestSelectedGroupNumber;
bool newGroupFlag = false;
// If the selected rows do not contain all rows with group number equal to the smallest selected group number,
// then we need to create a new group whose group number is the smallest selected group number plus 1.
// This then implies that we need to add 1 to the group number of every row with a group number larger than the
// lowest selected group number (that is the original lowest selected number before we added 1).
if (groupNumbersNotSelected.Contains(smallestSelectedGroupNumber))
{
newGroupNumber++;
newGroupFlag = true;
}
// Find which groups have been selected entirely, but ignore the smallest number.
// If a group has been entirely selected it means that that group number will no longer exist. Thus we will have to
// subtract 1 from each group number that is larger than a group that has been entirely selected. This process is
// cumulative, so if a number is higher than 2 entirely selected groups (excluding the smallest selected group) then
// we need to subtract 2 from the group number.
foreach (int group in groupNumbersSelected.Distinct())
{
if (!groupNumbersNotSelected.Contains(group) && !(group == smallestSelectedGroupNumber))
{
groupNumbersOfEntirelySelectedGroups.Add(group);
}
}
// Find the new group numbers
for (int r = 0; r < groupNumbersAll.Count; r++)
{
int groupNum = groupNumbersAll[r];
if (rowNumbersSelected.Contains(r))
{
groupNumbersAll[r] = newGroupNumber;
}
else
{
int subtract = groupNumbersOfEntirelySelectedGroups.Where(num => num < groupNum).Count();
if (newGroupFlag && groupNum >= newGroupNumber)
{
groupNum++;
}
groupNumbersAll[r] = groupNum - subtract;
}
}
//// Unbind the data table because of weird ass sorting error: https://stackoverflow.com/questions/30785736/editing-datagridview-data-changes-row-orders/30799185#30799185
//DataTable dt = (DataTable)dgvVolReport.DataSource;
//dgvVolReport.DataSource = null;
////Alter the values on the underlying DataTable
//for (int r = 0; r < groupNumbersAll.Count; r++)
//{
// dt.Rows[r]["Group"] = groupNumbersAll[r];
//}
////Rebind
//dgvVolReport.DataSource = dt;
//((DataView)dgvVolReport.DataSource).Sort = null;
int counter = 0;
foreach (DataGridViewRow row in dgvVolReport.Rows)
{
row.Cells["colGroup"].Value = groupNumbersAll[counter++];
}
dgvVolReport.Sort(colGroup, ListSortDirection.Ascending);
}
}
【问题讨论】:
-
不确定我是否理解,这与我使用的代码相同吗?组号不是行号。
-
我怀疑这与您正在进行的排序有关。 colGroup 是否参与排序?如果你在错误的时间排序,那么你的索引就会不同步。
-
我在当前设置断点的行上调用 sort。每次值更改时都会自动调用 sort 吗?也许我只需要关闭它...
-
所以我尝试在循环之前将该列的
SortMode转换为.Programmatic,然后将abck 转换为.Automatic,这确实解决了它。但是,如果我注释掉这一行(发生在循环之后以及在我打破并检查上面显示的值的点之后):dgvVolReport.Sort(colGroup, ListSortDirection.Ascending);那么它突然就起作用了。 所以代码后面的那一行的存在会在它发生之前改变行为!!!我该如何解决这个问题?
标签: c# .net winforms sorting datagridview