DataGridView:如何使Enter键添加新行而不是更改当前单元格?

Zac*_*son 9 .net datagridview winforms

如何使Win键在Winforms中表现得像在DataGridViewTextBoxCell正常的Winforms中一样TextBox(向文本添加新行,而不是更改当前单元格)?

Zac*_*son 10

好吧,我发现了如何解决这个问题.首先,创建一个CustomDataGridViewTextBoxEditingControl派生自的类DataGridViewTextBoxEditingControl,并覆盖EditingControlWantsInputKey如下:

public class CustomDataGridViewTextBoxEditingControl : DataGridViewTextBoxEditingControl
    {
        public override bool EditingControlWantsInputKey(
        Keys keyData, 
        bool dataGridViewWantsInputKey)
        {
            switch (keyData & Keys.KeyCode)
            {
                case Keys.Enter:
                    // Don't let the DataGridView handle the Enter key.
                    return true;
                default:
                    break;
            }

            return base.EditingControlWantsInputKey(keyData, dataGridViewWantsInputKey);
    }
}
Run Code Online (Sandbox Code Playgroud)

这将停止DataGridView处理Enter键并更改当前单元格.但是,它不会使Enter键添加新行.(似乎DataGridViewTextBoxEditingControl已删除了Enter键的功能).因此,我们需要自己覆盖OnKeyDown和实现这些功能,如下所示:

protected override void OnKeyDown(KeyEventArgs e)
{
    switch (e.KeyCode & Keys.KeyCode)
    {
        case Keys.Enter:
            int oldSelectionStart = this.SelectionStart;
            string currentText = this.Text;

            this.Text = String.Format("{0}{1}{2}",
                currentText.Substring(0, this.SelectionStart),
                Environment.NewLine,
                currentText.Substring(this.SelectionStart + this.SelectionLength));

            this.SelectionStart = oldSelectionStart + Environment.NewLine.Length;
            break;
        default:
            break;
    }

    base.OnKeyDown(e);
}
Run Code Online (Sandbox Code Playgroud)

然后,创建一个CustomDataGridViewTextBoxCell派生自的类DataGridViewTextBoxCell,并覆盖该EditType属性以返回其类型CustomDataGridViewTextBoxEditingControl.

public class CustomDataGridViewTextBoxCell : DataGridViewTextBoxCell
{
    public override Type EditType
    {
        get
        {
            return typeof(CustomDataGridViewTextBoxEditingControl);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

完成这一步之后,你可以设置CellTemplate在现有的列属性的CustomDataGridViewTextBoxCell,也可以创建自派生的类DataGridViewColumnCellTemplate预设的CustomDataGridViewTextBoxCell,你将所有设置!


Ash*_*Ash 5

您可以通过将DataGridViewCellStyle.WrapMode属性设置为true 来完成此操作.来自MSDN:

如果包含文本的单元格的WrapMode为False,则单元格在单行上显示文本,并将任何嵌入的换行符显示为框字符.如果包含文本的单元格的WrapMode为True,则单元格将换行符显示为换行符,但也会包含超出单元格宽度的任何行.

您可以通过访问单元格上的Style属性或通过使用列的DefaultCellStyle访问列中的所有单元格来为特定单元格设置此项.

[更新]要在DataGridView中有选择地禁用Enter键,请将Message Filter添加到包含DataGridView的Form中,如下所示:

private KeyMessageFilter m_filter = null;

private void Form1_Load(object sender, EventArgs e)
{
    m_filter = new KeyMessageFilter(this); 
    Application.AddMessageFilter(m_filter);

}
Run Code Online (Sandbox Code Playgroud)

这是消息过滤器类:

public class KeyMessageFilter : IMessageFilter
{
    private Form m_target = null;

    public KeyMessageFilter(Form targetForm)
    {
        m_target = targetForm;
    }

    private const int WM_KEYDOWN = 0x0100;

    private const int WM_KEYUP = 0x0101;


    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == WM_KEYDOWN)
        {
            //Note this ensures Enter is only filtered if in the 
            // DataGridViewTextBoxEditingControl and Shift is not also  pressed.
            if (m_target.ActiveControl != null && 
                m_target.ActiveControl is DataGridViewTextBoxEditingControl && 
                (Keys)m.WParam == Keys.Enter && 
                (Control.ModifierKeys & Keys.Shift) != Keys.Shift)
            {
                return true;
            }

        }

        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,编辑文本时禁用Enter键,您必须按Tab键才能移动到下一个单元格.Shift + Enter仍为您正在编辑的文本添加换行符.

希望这可以帮助.