C# 在用户按键上搜索 datagridview
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/797946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Search datagridview on user keypress
提问by Johann J.
I'm trying to select the first row where the cell value starts with the same keychar the user pressed. That's the part that is giving me trouble.
我正在尝试选择单元格值以用户按下的相同 keychar 开头的第一行。这就是给我带来麻烦的部分。
Here's how I'm handling the event (updated with working solution):
这是我处理事件的方式(使用工作解决方案更新):
private void dataGridView1_KeyPress(object sender, KeyPressEventArgs e)
{
if (Char.IsLetter(e.KeyChar))
{
for (int i = 0; i < (dataGridView1.Rows.Count); i++)
{
if (dataGridView1.Rows[i].Cells["Name"].Value.ToString().StartsWith(e.KeyChar.ToString(), true, CultureInfo.InvariantCulture))
{
dataGridView1.Rows[i].Cells[0].Selected = true;
return; // stop looping
}
}
}
}
I'm sure it's something simple that I'm overlooking, but for the life of me can't figure out what it is.
我敢肯定这是我忽略的一些简单的事情,但对于我的生活,我无法弄清楚它是什么。
EDIT
编辑
Updated the code with solution applied
使用解决方案更新了代码
采纳答案by SwDevMan81
Might be a case issue, is the Value in Cells["Name"] start with a capital letter? Try using ToUpper or ToLower on both; or you could try StartsWith(e.KeyChar, true) to ignoreCase. If you are trying to select the row, you'll want to do dataGridView1.Rows[i].Selected = true
可能是大小写问题,Cells["Name"] 中的值是否以大写字母开头?尝试在两者上使用 ToUpper 或 ToLower;或者你可以尝试 StartsWith(e.KeyChar, true) 来忽略大小写。如果您尝试选择行,则需要执行 dataGridView1.Rows[i].Selected = true
回答by xyz
if (Char.IsLetterOrDigit(e.KeyChar))
{
foreach (DataGridViewRow dgvRow in myDgv.Rows)
{
if (dgvRow.Cells["ColumnName"].FormattedValue
.ToString().StartsWith(e.KeyChar.ToString(), true, CultureInfo.InvariantCulture))
{
dgvRow.Selected = true;
break;
}
}
}
If the DGV is set up to allow Multi-Select then you'd obviously want to deselect any existing selection.
如果 DGV 设置为允许多选,那么您显然希望取消选择任何现有选择。
回答by user39074
This is a VS2008 VB.NET DataGridView extension meant to do kind of what you are doing but using a TextBox for searching information (not designed with case in mind but could easily be added). This extension works so perhaps there is something that might be helpful. I did notice that your code selects a row using select where mine uses CurrentCell.
这是一个 VS2008 VB.NET DataGridView 扩展,旨在完成您正在做的事情,但使用 TextBox 来搜索信息(设计时不考虑大小写,但可以轻松添加)。这个扩展有效,所以也许有些东西可能会有所帮助。我确实注意到您的代码使用 select 选择一行,而我的代码使用 CurrentCell。
<Runtime.CompilerServices.Extension()> _
Public Function PartSeek(ByVal GridView As DataGridView, ByVal ColumnName As String, ByVal Value As String, ByVal Part As Boolean) As Boolean
Dim Located As Boolean = False
If GridView.Columns.Contains(ColumnName) Then
Dim SingleRow As DataGridViewRow
If Part Then
SingleRow = (From Rows In GridView.Rows.Cast(Of DataGridViewRow)() _
Where Rows.Cells(ColumnName).Value.ToString().Contains(Value)).FirstOrDefault
Else
SingleRow = (From Rows In GridView.Rows.Cast(Of DataGridViewRow)() _
Where Rows.Cells(ColumnName).Value.ToString() = Value).FirstOrDefault
End If
If Not IsNothing(SingleRow) Then
If GridView.CurrentCell.RowIndex <> SingleRow.Index Then
GridView.CurrentCell = GridView(0, SingleRow.Index)
End If
DirectCast(GridView.Parent, Form).ActiveControl = GridView
Located = True
End If
Return Located
Else
Throw New Exception("Column '" & ColumnName & "' not contained in this DataGridView")
End If
End Function
回答by Amberlea Moore
I use this in VB.NET. You can use http://www.developerfusion.com/tools/to convert to C Sharp.
我在 VB.NET 中使用它。您可以使用http://www.developerfusion.com/tools/转换为 C Sharp。
I wrote a method that will select row letter typed. The function is called in the KeysPress event handler of the DataGridView.
我写了一个方法来选择输入的行字母。该函数在 DataGridView 的 KeysPress 事件处理程序中调用。
Method:
方法:
'user types letter in dgv, method will select the column starting with that letter if it exists or else next letter existing in dgv
Public Shared Sub GoToLetterTypedInDataGridView(ByVal dgv As DataGridView, ByVal columnName As String, ByVal columnPosition As Integer, ByVal letterTyped As Char)
Try
Dim dt As DataTable = dgv.DataSource
Dim letter As Char = letterTyped
Dim dv As DataView = New DataView(dt)
Dim hasCount As Boolean = False
While (Not hasCount)
dv.Sort = columnName
dv.RowFilter = columnName & " like '" & letter & "%'"
If dv.Count > 0 Then
hasCount = True
Dim x As String = dv(0)(columnPosition).ToString()
Dim bs As New BindingSource
bs.DataSource = dt
dgv.BindingContext(bs).Position = bs.Find(columnName, x)
dgv.CurrentCell = dgv(0, bs.Position)
Else
If letter = "z" Then
letter = "a"
ElseIf letter = "Z" Then
letter = "A"
Else : letter = Chr(Asc(letter) + 1)
End If
End If
End While
Catch ex As Exception
Dim stackframe As New Diagnostics.StackFrame(1)
Throw New Exception("An error occurred in routine, '" & stackframe.GetMethod.ReflectedType.Name & "." & System.Reflection.MethodInfo.GetCurrentMethod.Name & "'." & Environment.NewLine & " Message was: '" & ex.Message & "'")
End Try
End Sub
Then to call:
然后调用:
Private Sub dgvNew_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles dgvNew.KeyPress
Try
If dgvNew.RowCount > 0 Then
GoToLetterTypedInDataGridView(dgvNew, "columnName", 0, e.KeyChar)
End If
Catch ex As Exception
Dim stackframe As New Diagnostics.StackFrame(1)
Throw New Exception("An error occurred in routine, '" & stackframe.GetMethod.ReflectedType.Name & "." & System.Reflection.MethodInfo.GetCurrentMethod.Name & "'." & Environment.NewLine & " Message was: '" & ex.Message & "'")
End Try
End Sub
结束子
Hope this helps! Amber
希望这可以帮助!琥珀色
回答by TBD
The edited answer in the original question doesn't support jumping to the next letter if there are multiple instances of names starting with the same letter. Here is an edited answer which support this feature:
如果有多个以相同字母开头的名称实例,则原始问题中编辑后的答案不支持跳转到下一个字母。这是支持此功能的编辑答案:
private void dataGridView1_KeyPress(object sender, KeyPressEventArgs e)
{
if (Char.IsLetter(e.KeyChar))
{
int index = 0;
// This works only if dataGridView1's SelectionMode property is set to FullRowSelect
if (dataGridView1.SelectedRows.Count > 0 )
{
index = dataGridView1.SelectedRows[0].Index + 1
}
for (int i = index; i < (dataGridView1.Rows.Count + index); i++)
{
if (dataGridView1.Rows[i % dataGridView1.Rows.Count].Cells["Name"].Value.ToString().StartsWith(e.KeyChar.ToString(), true, CultureInfo.InvariantCulture))
{
foreach (var row in dataGridView1.Rows.Cast<DataGridViewRow>().Where(t => t.Selected))
{
row.Selected = false;
}
dataGridView1.Rows[i % dataGridView1.Rows.Count].Cells[0].Selected = true;
return; // stop looping
}
}
}
}