KeyDown事件与Datagridview的RowHeaderVisible的关系

时间:2010-10-01 11:05:18

标签: c# winforms datagridview keyboard

我使用的软件:C#,VS-2005。

我在datagridview中有一个填充的组合框。我注意到,当datagridview属性RowHeaderVisible设置为false时,编辑控件不会触发任何keydown事件。但是,当我将RowHeaderVisible设置为true时,keydown事件正常工作。

所以,我知道设置为RowHeaderVisible的{​​{1}}属性可行。但是根据我的要求,没有必要将其设置为true

我想知道这种行为的原因,以及如何克服它。

我的代码是:

true

以上代码代表入口点。我的意思是用户输入数据。我在datagridview中使用sql数据库填充了combobox。组合框具有帐户名称列表。用户根据需要选择它,然后在金额列中输入数据并保存。

这就是全部。但是你可以看到它有一个问题。根据我的评论,位于“tergive”的答案之下。

2 个答案:

答案 0 :(得分:1)

以下是在表单上使用ProcessCmdKey而不是使用自定义DGV的替代表单:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

class Form1 : Form
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    DataGridView dgv;

    public Form1()
    {
        Text = "Form1";

        dgv = new DataGridView();
        dgv.Dock = DockStyle.Fill;
        DataGridViewComboBoxColumn dgvColumn = new DataGridViewComboBoxColumn();
        dgvColumn.HeaderText = "Header";
        dgvColumn.DataSource = new string[] { "One", "Two", "Three", "Four" };
        dgv.Columns.Add(dgvColumn);
        Controls.Add(dgv);

        Button button = new Button();
        button.Text = "Place holder";
        button.Dock = DockStyle.Top;
        Controls.Add(button);
    }

    [DllImport("user32.dll")]
    private static extern bool IsChild(IntPtr hwndParent, IntPtr hwndChild);

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if ((keyData & (Keys.Alt | Keys.C)) == (Keys.Alt | Keys.C))
        {
            if (dgv.Handle == msg.HWnd || IsChild(dgv.Handle, msg.HWnd))
            {
                Form form = new Form();
                form.Text = "Form2";
                form.Show(this);
                return true;
            }
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }
}

答案 1 :(得分:0)

控件不提供外部连接“命令键”的好方法。查找命令键的最佳位置是覆盖ProcessCmdKey。所以你基本上有两个选择:

1)覆盖表单上的ProcessCmdKey,并在调用期间检查DGV(或其中一个子节点)是否具有键盘焦点。

2)创建一个自定义DGV并在那里覆盖ProcessCmdKey。

我过去使用了#2并创建了以下内容以允许外部访问事件(父窗体)。

扩展示例

using System;
using System.Windows.Forms;

class Form1 : Form
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    public Form1()
    {
        Text = "Form1";

        CustomDataGridView dgv = new CustomDataGridView();
        dgv.Dock = DockStyle.Fill;
        DataGridViewComboBoxColumn dgvColumn = new DataGridViewComboBoxColumn();
        dgvColumn.HeaderText = "Header";
        dgvColumn.DataSource = new string[] { "One", "Two", "Three", "Four" };
        dgv.Columns.Add(dgvColumn);
        dgv.CommandKeyPress += new CommandKeyPressHandler(dgv_CommandKeyPress);
        Controls.Add(dgv);

        Button button = new Button();
        button.Text = "Place holder";
        button.Dock = DockStyle.Top;
        Controls.Add(button);
    }

    bool dgv_CommandKeyPress(object sender, Keys keyData)
    {
        if ((keyData & (Keys.Alt | Keys.C)) == (Keys.Alt | Keys.C))
        {
            Form form = new Form();
            form.Text = "Form2";
            form.Show(this); 
            return true;
        }
        return false;
    }
}

delegate bool CommandKeyPressHandler(object sender, Keys keyData);

class CustomDataGridView : DataGridView
{
    public event CommandKeyPressHandler CommandKeyPress;

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        CommandKeyPressHandler eventDelegate = CommandKeyPress;
        if (eventDelegate != null)
        {
            foreach (CommandKeyPressHandler handler in eventDelegate.GetInvocationList())
            {
                if (handler(this, keyData))
                    return true;
            }
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }
}