I have DataGridView which is bounded with a datatable. I fill this datatable from database. I have 2 buttons right next to the datagridview, Up and Down. the rows should move up and down based on whichever button i click. I understand there are many answers for the similar issues but they work if your gridview isnt bounded. I also have a sequence column which has numbers from 0 onwards. When the rows move up or down, the sequence should be fixed as well. For example, if i move row[12] up, the sequence of row[12] should update to row[11] and row[11] should move down and row[11] sequence becomes row[12]. (I'm sorry if this is confusing). I also have 2 event functions attached to up and down buttons as well.
我有一个绑定了DataTable的DataGridView。我从数据库填充这个数据表。我有2个按钮旁边的数据网格视图,向上和向下。行应该根据我单击的任何按钮上下移动。我知道对于类似的问题有很多答案,但如果你的网格视图不受限制,它们就会奏效。我还有一个序列列,它的数字从0开始。当行向上或向下移动时,顺序也应该是固定的。例如,如果我将行[12]上移,则行[12]的序列应更新为行[11],行[11]应下移,行[11]序列应变为行[12]。(如果这让人困惑,我很抱歉)。我也有2个事件功能附加到向上和向下按钮以及。
Edit: The main goal of this gridview is that user can add new rows as well. So, along with the above information, if there are 5 rows with sequence 1 to 5, and the user adds another row with sequence 2. I can sort the rows but how do I make the origninal rows with sequence 2,3,4,5 shift down and change their sequence to 3,4,5,6?
编辑:这个网格视图的主要目标是用户也可以添加新行。因此,连同上述信息,如果有5行具有序列1到5,并且用户添加另一行具有序列2。我可以对行进行排序,但是我如何使序列为2,3,4,5的原始行向下移动并将其序列更改为3,4,5,6?
private void moveRow(int position)
{
DataRow selectedDataRow = null;
DataRow newDataRow = null;
int sequence = -1;
int newSequence = -1;
DataGridViewRow selectedRow = dataGridView.SelectedRows[0];
sequence = (int)selectedRow.Cells[sequenceDataGridViewTextBoxColumn.Index].Value;
newSequence = sequence + position;
if (newSequence <= 0 || newSequence > dataGridView.Rows.Count)
{
return;
}
//below code doesnt work at all maybe cuz it isnt right
//How do i select the current row and the row at the new sequence?????
if (selectedDataRow != null && newDataRow != null)
{//below i try to assign sequences to the rows
selectedDataRow["Sequence"] = newSequence;
newDataRow["Sequence"] = sequence;
}
dataGridViewRed.Sort(dataGridViewRed.Columns[buildSequenceDataGridViewTextBoxColumn.Index], ListSortDirection.Ascending);// i sort it again based on sequence
dataGridViewRed.CurrentCell = dataGridViewRed.Rows[selectedRow.Index + position].Cells[buildSequenceDataGridViewTextBoxColumn.Index];//highlight the current selected cell
//below functions are the events attached to the buttons for up and down
private void UpBtn_Click(object sender, EventArgs e)
{
moveRow(-1);
}
private void DownBtn_Click(object sender, EventArgs e)
{
moveRow(+1);
}
There are definitely some loopholes in my explanation so please be kind. I will do my best to explain any confusions, if need be.
我的解释肯定有漏洞,所以请多多关照。如有需要,我会尽我所能解释任何混淆之处。
更多回答
Why not sort by the the sequence value(s) and just maintain that rather than trying to manage rows in a bound control?
为什么不按Sequence值(S)进行排序并保持该值,而不是尝试管理绑定控件中的行?
let me edit my question. i forgot a major point. Sorry.
让我编辑一下我的问题。我忘了一个要点。抱歉的。
When they add, loop thru the datasource and update the IDs which are 2 or above. If you are using the proper collection type the DGV will (re)sort itself. You arent supposed to try to manage DGV rows in a bound control
当它们相加时,循环遍历数据源并更新大于或等于2的ID。如果您使用正确的集合类型,DGV将自动(重新)排序。您不应该尝试管理绑定控件中的DGV行
优秀答案推荐
If your rows are bound, then following example is applicable for moving row up. Prober Bounding should take care about sorting the DataGridView
on the screen. If you sorted it in the data bound source, then it should work without .Sort
, I think (I didn't test that).
如果您的行是绑定的,则以下示例适用于上移行。探测边界应注意对屏幕上的DataGridView进行排序。如果您在数据绑定源中对其进行了排序,那么它应该可以在没有.Sort的情况下工作,我认为(我没有对此进行测试)。
If the row numbering could be inconsistent (c#):
如果行号可能不一致(c#):
DataGridViewRow SelectedDataRow = ...;
if (SelectedDataRow.Index > 0)
{
DataGridViewRow PrevDataRow = DataGridView1.Rows(SelectedDataRow.Index - 1);
Int16 PrevSequence = PrevDataRow.Cells("Sequence").Value; // buffer the previous sequence
PrevDataRow.Cells("Sequence").Value = SelectedDataRow.Cells("Sequence").Value; // set previous sequence to selected
SelectedDataRow.Cells("Sequence").Value = PrevSequence; // set selected to previous
}
VB.NET:
VB.NET:
Dim SelectedDataRow As DataGridViewRow = ...
If SelectedDataRow.Index > 0 Then
Dim PrevDataRow As DataGridViewRow = DataGridView1.Rows(SelectedDataRow.Index - 1)
Dim PrevSequence As Int16 = PrevDataRow.Cells("Sequence").Value ' buffer the previous sequence
PrevDataRow.Cells("Sequence").Value = SelectedDataRow.Cells("Sequence").Value ' set previous sequence to selected
SelectedDataRow.Cells("Sequence").Value = PrevSequence ' set selected to previous
End If
If the rownumbering is consistent (continuous 1 to N), then it can be simplified:
如果行号一致(从1到N连续),则可以简化:
DataGridViewRow SelectedDataRow = ...;
if (SelectedDataRow.Index > 0)
{
DataGridViewRow PrevDataRow = DataGridView1.Rows(SelectedDataRow.Index - 1);
PrevDataRow.Cells("Sequence").Value = SelectedDataRow.Index + 1;
SelectedDataRow.Cells("Sequence").Value = SelectedDataRow.Index; // set selected to previous
}
VB.NET:
VB.NET:
Dim SelectedDataRow As DataGridViewRow = ...
If SelectedDataRow.Index > 0 Then
Dim PrevDataRow As DataGridViewRow = DataGridView1.Rows(SelectedDataRow.Index - 1)
PrevDataRow.Cells("Sequence").Value = SelectedDataRow.Index + 1
SelectedDataRow.Cells("Sequence").Value = SelectedDataRow.Index ' set selected to previous
End If
The moving down is similar, just the condition takes into account a limit of number of rows.
向下移动是相似的,只是条件考虑了行数的限制。
While this worked for me in similar scenario, I usually don't use binding in such scenarios, I use a DataTable as a data mediator.
虽然这在类似的场景中适用于我,但在这种场景中我通常不使用绑定,我使用DataTable作为数据中介器。
Up
向上
if (dataGridView1.SelectedRows.Count == 1)
{
DataGridViewRow Row = dataGridView1.SelectedRows[0];
if (Row.Index > 0)
{
var Index = Row.Index;
var OldRow = (DataGridViewRow)Row.Clone();
for (int i = 0; i < OldRow.Cells.Count; i++)
OldRow.Cells[i].Value = Row.Cells[i].Value;
dataGridView1.Rows.RemoveAt(Index);
dataGridView1.Rows.Insert(Index-1, OldRow);
}
}
Down
降下来
if (dataGridView1.SelectedRows.Count == 1)
{
DataGridViewRow Row = dataGridView1.SelectedRows[0];
if (Row.Index < dataGridView1.Rows.Count-1)
{
var Index = Row.Index;
var OldRow = (DataGridViewRow)Row.Clone();
for (int i = 0; i < OldRow.Cells.Count; i++)
OldRow.Cells[i].Value = Row.Cells[i].Value;
dataGridView1.Rows.RemoveAt(Index);
dataGridView1.Rows.Insert(Index + 1, OldRow);
}
}
更多回答
Your answer works. but i had to change PrevDataRow.Cells("Sequence").Value = SelectedDataRow.Index + 1; SelectedDataRow.Cells("Sequence").Value = SelectedDataRow.Index;
to the following: PrevDataRow.Cells("Sequence").Value = SelectedDataRow.Index; SelectedDataRow.Cells("Sequence").Value = SelectedDataRow.Index+1;
你的回答奏效了。但我必须将PrevDataRow.Cells(“Sequence”).Value=SelectedDataRow.Index+1;SelectedDataRow.Cells(“Sequence”).Value=SelectedDataRow.Index;更改为:PrevDataRow.Cells(“Sequence”).Value=SelectedDataRow.Cells(“Sequence”).Value=SelectedDataRow.Index+1;
Sorry for that, the former is for row numbering starting with 0. Glad it helped a bit.
很抱歉,前者用于从0开始的行号。很高兴它帮了我一点忙。
我是一名优秀的程序员,十分优秀!