我正在DataGridView
中托管自定义编辑控件,该记录在TextBox
中与Button
和UserControl
一起记录。我从DataGridViewColumn
继承了新列,DataGridViewTextBoxCell
继承了新列。
如果正常DataGridViewTextBoxCell
,如果您在单元格有焦点时按某个键,它将开始编辑模式和您输入的字符将显示在TextBoxEditingControl
中。但是,在我继承的单元格中,没有值传递给keypress。 (实际上,您必须手动传递InitializeEditingControl
中的当前单元格值,否则根本不会显示任何内容。)因此,您键入的第一个字符(开始编辑模式的字符)将丢失。
我在OnKeyPress
中尝试了OnKeyDown
,OnKeyUp
和DataGridViewCell
,但他们从未被调用过。然而,KeyEntersEditMode
似乎确实被调用,并且只有在检查按下的键时,所以这可能是一个好的起点。那么问题就变成了如何将KeyEventArgs转换为char
。这对于字母和数字来说是微不足道的,但由于并非所有键盘都是相同的,因此处理其他键时最多也是混乱和复杂的。如果有一个转换器类可以自动执行此操作,请赐教。
是否有其他人遇到此问题或找到了一个好的解决方法?
注意:当EditMode
设置为EditOnKeystroke
的任何变体时,此问题适用。设置为EditOnEnter
是我的项目的有效解决方法,但我也想模拟TextBoxEditingControl
的默认行为。
答案 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
中添加映射到SendMessageVB.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)完成。