在进入编辑模式时捕获第一个字符 - 在DataGridView中自定义编辑控件

时间:2008-12-17 07:06:37

标签: .net winforms datagridview

我正在DataGridView中托管自定义编辑控件,该记录在TextBox中与ButtonUserControl一起记录。我从DataGridViewColumn继承了新列,DataGridViewTextBoxCell继承了新列。

如果正常DataGridViewTextBoxCell,如果您在单元格有焦点时按某个键,它将开始编辑模式您输入的字符将显示在TextBoxEditingControl中。但是,在我继承的单元格中,没有值传递给keypress。 (实际上,您必须手动传递InitializeEditingControl中的当前单元格值,否则根本不会显示任何内容。)因此,您键入的第一个字符(开始编辑模式的字符)将丢失。

我在OnKeyPress中尝试了OnKeyDownOnKeyUpDataGridViewCell,但他们从未被调用过。然而,KeyEntersEditMode似乎确实被调用,并且只有在检查按下的键时,所以这可能是一个好的起点。那么问题就变成了如何将KeyEventArgs转换为char。这对于字母和数字来说是微不足道的,但由于并非所有键盘都是相同的,因此处理其他键时最多也是混乱和复杂的。如果有一个转换器类可以自动执行此操作,请赐教。

是否有其他人遇到此问题或找到了一个好的解决方法?

注意:当EditMode设置为EditOnKeystroke的任何变体时,此问题适用。设置为EditOnEnter是我的项目的有效解决方法,但我也想模拟TextBoxEditingControl的默认行为。

4 个答案:

答案 0 :(得分:1)

尝试将用户控件的KeyPreview设置为true。然后检查开始编辑过程的键是否触发了keydown,即使是用户控件也是如此。如果是,则只需在文本控件进入编辑模式后存储并分配字符。

答案 1 :(得分:1)

我的解决方案是覆盖自定义OnKeyPress上的UserControl

protected override void OnKeyPress(KeyPressEventArgs e)
{
  _textBox.Text = e.KeyChar.ToString();
  _textBox.SelectionStart = 1;
  _textBox.SelectionLength = 0;
  base.OnKeyPress(e);
}

答案 2 :(得分:0)

您好 今天我遇到了同样的问题。我的解决方案是覆盖CustomCell中的KeyEntersEditMode并添加一些算法来转换或确定一个字符是否有效传递给编辑控件。然后我将此值存储为私有变量。我重写InitializeEditingControl方法并使用我的存储值作为控件的初始值。使用它之后,我将其设置为null,以便以后什么都不会使用它。


private string startString;
public override bool KeyEntersEditMode(KeyEventArgs e)
{
    var result = base.KeyEntersEditMode(e);
    if (e.KeyData == Keys.D1)
    {
        startString = "1";
    }
    return result;
}

public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
    if(startString != null)
    {
        initialFormattedValue = startString;
        startString = null;
    }
    base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
    var c = this.DataGridView.EditingControl as MyEditingControl;
    string initialFormattedValueStr = initialFormattedValue as string;
    if (initialFormattedValueStr == null)
    {
        c.Text = string.Empty;
    }
    else
    {
        c.Text = initialFormattedValueStr;
        c.SelectionStart = initialFormattedValueStr.Length;
    }

}

答案 3 :(得分:0)

要将第一个字符放入TextBox,请执行以下操作:

1)添加“Imports System.Runtime.InteropServices”或使用,如果您更喜欢C#

2)在user32.dll

中添加映射到SendMessage
VB.Net example:
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function

C# example:
[DllImport("USER32.DLL", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

3)将密钥从UserControl重定向到TextBox

Protected Overrides Function ProcessKeyEventArgs(ByRef m As System.Windows.Forms.Message) As Boolean
    SendMessage(Me.ComboBox.Handle, m.Msg, m.WParam, m.LParam)
    Return True
End Function

protected override bool ProcessKeyEventArgs(ref Message m)
{
    SendMessage(textBox.Handle, m.Msg, m.WParam, m.LParam);
    return true;
}

4)有example on Microsoft page with the DataGridViewNumericUpDown here,下载源代码。

5)完成。