[英]Selected rows when sorting DataGridView in WinForm application
在 WinForm 應用程序 C# 4.0 中,我有一個綁定到 SortableBindingList 的 DataGridView。 因此,可以通過單擊標題列對其進行排序 - 到目前為止一切正常;-)
問題是,所選行似乎被行號“記住”了。 這是發生的事情:
A* <- "Selected"
B
C
現在按降序排序,C 在頂部並被選中。 我想仍然選擇 A:
C* <- "Selected"
B
A <- "Want have"
選擇多行時也會發生同樣的情況。 有解決方法嗎?
您可以通過在排序之前存儲當前選定行(或多行)的值,然后在之后重新選擇該行來解決此問題。
您需要使用 CellMouseDown 事件 - 必須使用此事件,因為它是唯一在排序發生之前觸發的事件。 像 ColumnHeaderMouseClick 這樣的替代事件都太晚了。
在 CellMouseDown 事件處理程序中,檢查行索引是否為 -1 以確保選擇了標題。
void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex == -1)
{
selected = dataGridView1.SelectedRows[0].Cells[0].Value.ToString();
}
}
我有一個類層次字段selected
,我使用來存儲所選擇的列的唯一標識符。 如果您沒有唯一的 id,那么您可以為此目的添加一列並將其隱藏。
然后在 DataGridView 的Sorted
eventhandler 中,您可以使用網格綁定源的 .Find() 方法:
void dataGridView1_Sorted(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(selected))
{
int itemFound = _bindingSource.Find("name", selected);
_bindingSource.Position = itemFound;
}
}
在對此進行調查時,我在 MSDN 論壇上發現了以下帖子,其中答案使用 DataBindingComplete 事件 - 我不是 100% 為什么他們認為這是必要的,因為我的方法適用於我的所有測試,但您可能會發現它是一個有用的參考。
這是我在 VB.NET 中的方法
Private cSelectedRow As String
Private Sub DataGridView1_CellMouseDown(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseDown
If e.RowIndex = -1 AndAlso DataGridView1.SelectedRows.Count > 0 Then
cSelectedRow = DataGridView1.SelectedRows(0).Cells("ID").Value.ToString()
End If
End Sub
我使用了與 David Hall 相同的事件,但沒有使用BindingSource
。 所以我遍歷網格的所有行以找到之前選擇的行。
Private Sub DataGridView1_Sorted() Handles DataGridView1.Sorted
DataGridView1.ClearSelection()
For Each xRow As DataGridViewRow In DataGridView1.Rows
If xRow.Cells("ID").Value = cSelectedRow Then
DataGridView1.CurrentCell = xRow.Cells(0)
'Line Found. No need to loop through the rest.
Exit For
End If
Next
End Sub
我嘗試了 David Hall 的答案,但對我的網格中排序操作的三種狀態之一沒有用,所以我在MyDataGridView.cs
類中更改了一些MyDataGridView.cs
,如下所示:
public string SelectedValue { get; set; }
private bool headerFirstClick = true;
public bool HeaderWasClicked = false;
private void MyDataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
try
{
if (headerFirstClick) Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.None;
if (Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection == SortOrder.None)
{
Columns[e.ColumnIndex].SortMode = DataGridViewColumnSortMode.Automatic;
Sort(Columns[e.ColumnIndex], System.ComponentModel.ListSortDirection.Ascending);
Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
}
else if (Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection == SortOrder.Ascending)
{
Columns[e.ColumnIndex].SortMode = DataGridViewColumnSortMode.Programmatic;
((BindingSource)DataSource).Sort = string.Empty;
Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.None;
}
headerFirstClick = false;
int findValue = ((BindingSource)DataSource).Find(Columns[e.ColumnIndex].Name, SelectedValue);
((BindingSource)DataSource).Position = findValue;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
protected override void OnCellClick(DataGridViewCellEventArgs e)
{
base.OnCellClick(e);
if (e != null)
{
try
{
HeaderWasClicked = (e.RowIndex == -1);
SelectedValue = SelectedRows[0].Cells[e.ColumnIndex].Value.ToString();
}
catch(Exception){}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.