4

我在 a 中托管了一个自定义编辑控件,DataGridView据记录,它是 aTextBoxButton一起在 a 中UserControl。我继承DataGridViewColumn了新列和DataGridViewTextBoxCell新单元格。

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

我已经尝试过OnKeyPress,OnKeyDownOnKeyUpin ,DataGridViewCell但他们从未被调用过。KeyEntersEditMode但是,似乎确实被调用了,并且仅在它检查按下的键时才被调用,因此这可能是一个不错的起点。那么问题就变成了如何将 KeyEventArgs 转换为char. 这对于字母和数字来说是微不足道的,但由于并非所有键盘都是平等的,因此处理其他键充其量是混乱和复杂的。如果有一个转换器类可以自动执行此操作,请赐教。

有没有其他人遇到过这个问题或找到了一个好的解决方法?

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

4

4 回答 4

1

尝试将用户控件的 KeyPreview 设置为 true。然后检查启动编辑过程的键是否会触发 keydown,即使对于用户控件也是如此。如果是这样,您可以在文本控件进入编辑模式后简单地存储和分配字符。

于 2009-06-09T10:27:40.630 回答
1

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

protected override void OnKeyPress(KeyPressEventArgs e)
{
  _textBox.Text = e.KeyChar.ToString();
  _textBox.SelectionStart = 1;
  _textBox.SelectionLength = 0;
  base.OnKeyPress(e);
}
于 2009-07-01T06:31:36.700 回答
0

Hi Today I had the same problem. My solution is to override KeyEntersEditMode in CustomCell and put there some algorithm to convert or to determine if a character is valid for passing to the editing control. Then I store this value as a private variable. I override the InitializeEditingControl method and use my stored value as the initial value for the control. After using it I set it to null so that later nothing would use it.


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

}
于 2011-01-31T12:59:25.980 回答
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)微软页面上有示例,这里有DataGridViewNumericUpDown,下载源代码。

5) 完成。

于 2012-02-24T22:29:07.290 回答