在用户按键上搜索datagridview

时间:2009-04-28 13:30:41

标签: c# .net winforms datagridview keypress

我正在尝试选择单元格值以用户按下的相同keychar开头的第一行。那是给我带来麻烦的部分。

以下是我处理活动的方式(使用工作解决方案更新):

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
            }
        }
    }
}

我确信这是一件很简单的事,我忽略了,但是因为我的生活无法弄清楚它是什么。

修改

使用解决方案更新了代码

5 个答案:

答案 0 :(得分:4)

可能是一个案例问题,单元格中的值[“名称”]是否以大写字母开头?尝试在两者上使用ToUpper或ToLower;或者你可以尝试使用StartsWith(e.KeyChar,true)来忽略它。如果您尝试选择行,则需要执行dataGridView1.Rows [i] .Selected = true

答案 1 :(得分:2)

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;
        }
    }
}

如果DGV设置为允许多选,那么您显然想要取消选择任何现有选择。

答案 2 :(得分:2)

如果有多个以相同字母开头的名称实例,原始问题中的编辑答案不支持跳转到下一个字母。 以下是支持此功能的已编辑答案:

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
            }
        }
    }
}

答案 3 :(得分:1)

这是一个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

答案 4 :(得分:1)

我在VB.NET中使用它。您可以使用http://www.developerfusion.com/tools/转换为C Sharp。

我编写了一个选择输入行号的方法。该函数在DataGridView的KeysPress事件处理程序中调用。

方法:

'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

然后致电:

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

希望这有帮助! 琥珀