KeyUp事件未在DataGrid上触发

时间:2015-03-17 11:57:06

标签: c# events datagrid compact-framework

无法理解为什么不是,这是示例代码:

public Form1()
        {
            InitializeComponent();
            //Create DataGrid
            DataGrid dg = new DataGrid();
            dg.Parent = this;
            dg.Location = new Point(10, 10);
            dg.Size = new System.Drawing.Size(300, 200);
            //Create list of people
            List<Person> people = MethodThatFetchesPeople();
            //Bind list
            BindingList<Person> bl_people = new BindingList<Person>(people);
            dg.DataSource = bl_people;
            //Format grid
            dg.TableStyles.Clear();
            DataGridTableStyle dgts = new DataGridTableStyle();
            dgts.MappingName = bl_people.GetType().Name;
            dgts.ReadOnly = true;
            DataGridTextBoxColumn col_name = new DataGridTextBoxColumn();
            col_name.MappingName = "Name";
            col_name.HeaderText = "Name";
            dgts.GridColumnStyles.Add(col_name);
            DataGridTextBoxColumn col_height = new DataGridTextBoxColumn();
            col_height.MappingName = "Height";
            col_height.HeaderText = "Height (cm)";
            dgts.GridColumnStyles.Add(col_height);
            dg.TableStyles.Add(dgts);
            //Subscribe events
            col_name.TextBox.KeyDown += new KeyEventHandler(TextBox_KeyDown);
            col_name.TextBox.KeyUp += new KeyEventHandler(TextBox_KeyUp);
        }

事件处理方法:

        void TextBox_KeyUp(object sender, KeyEventArgs e)
        {
            //Do something on keyup
            Debug.WriteLine("Keyup!");
        }

        void TextBox_KeyDown(object sender, KeyEventArgs e)
        {
            //Do something on keydown
            Debug.WriteLine("Keydown!");
        }
    }

按下名称列中的值后, DataGridTextBoxColumn 将获得焦点。 然后每当我按下某个键时, KeyDown 事件就会被触发,但 KeyUp 事件没有任何反应,即使未订阅 KeyDown 事件也是如此。
我真的只需要KeyUp事件,KeyDown不符合我的目的。我不能只是切换到 DataGridView ,因为此代码将与紧凑框架一起使用:(
我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

我已经看到这种情况特别发生在Windows窗体/桌面应用程序上,但在此处发布,以防它在移动设备上也适用。

DataGrid控件习惯于“吞咽”某些键盘事件。它在内部处理它们(我相信它们由各个网格单元处理)并且它们不会“冒泡”到其他控件,因为事件已被消耗。

有两种不同的方法可以做到这一点。基本上,您需要设置表单以在事件到达DataGrid之前拦截事件,然后预处理并决定是否还要将事件传递给DataGrid。

要在应用程序内创建“通用过滤器”,请执行以下操作。如果您遵循调度程序模式并且可能需要将键击路由到许多不同控件之一,则可以执行此操作:

在Form的构造函数中:

this.KeyPreview = true;
Application.AddMessageFilter(this);

在表单中覆盖此方法。如果此方法返回“true”,则将消耗该事件,并且不会将该事件分派给任何其他控件。如果此方法返回“false”,则事件将正常通过所有控件。

    // This is the ONLY way to prevent buttons, checkboxes, and datagrids from processing the UP and DOWN arrows
    const int WM_KEYDOWN       = 0x100;
    const int WM_KEYUP         = 0x101;
    public bool PreFilterMessage(ref Message m)
    {
        try
        {

            if (m.Msg == WM_KEYDOWN)
                // handle event here and return true
            else if (m.Msg == WM_KEYUP)
                // handle event here and return true
            }
        }
        catch
        {
            return false;
        }

    return false;
    }

我在大约10年前写过/想出了所有这些,所以也许有其他/更好的方法来做到这一点,但这对我有用,我不必创建任何控件的自定义实现来使其工作。< / p>


我在MSDN文章中找到的另一种技术。它是为VB编写的,但应该很容易翻译成C#:

https://support2.microsoft.com/default.aspx?scid=kb;en-us;320583&Product=vbNET

这里的基本前提是继承DataGrid并覆盖ProcessCmdKey方法。

答案 1 :(得分:0)

这个MSDN Article表明CF中的键盘事件处理并不容易,但它可以提供解决方案。我没有全部阅读。