【问题标题】:How to override PreviewKeyDown on a TextBox?如何覆盖 TextBox 上的 PreviewKeyDown?
【发布时间】:2014-04-05 15:46:12
【问题描述】:

我在我制作的控件内的 TextBox 上有一个 PreviewKeyDown 事件处理程序,它检查用户是否按下了向下键。当控件位于布局容器(如网格)内时,事件处理程序正确处理按键。但是,如果我将控件放在 DataGrid 的 DataGridTempalteColumn 中,则控件不会执行我需要它执行的操作。

我认为问题在于,因为 PreviewKeyDown 采用隧道策略,所以主机 DataGrid 可以在我的控件之前处理向下箭头键按下。对于向下箭头,DataGrid 将焦点移动到下一行。 DataGrid 似乎没有将 IsHandled 设置为 true,因为事件最终由我控制,但它仍然在事件上做自己的事情,这对我来说是个问题。

问题不在于 DataGrid,而在于我的控件有一个来自 TextBox 的隧道 PreviewKeyDown 事件。我正在寻找一种方法来覆盖 TextBox 上的这个默认事件。也许我可以对附加行为做些什么?也许我需要从 TextBox 继承然后覆盖?到目前为止,我还没有找到任何表明如何处理这种情况的东西。

下面是这个问题的原文,没有得到任何答案

我在使用作为 DataGridTemplateColumn 中的 DataTemplate 制作的自定义自动完成文本框时遇到了困难。

 <DataGrid.Columns>
                            <DataGridTemplateColumn Header="Material" Width="300">
                                <DataGridTemplateColumn.CellEditingTemplate>
                                    <DataTemplate>
                                        <local:actextbox Text="{Binding Path=Description, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                                                         MatchList="{Binding Path=DataContext.LaborTemplatesList, RelativeSource={RelativeSource AncestorType=UserControl, AncestorLevel=2}}"/>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellEditingTemplate>
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Path=Description}"/>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>

                        </DataGrid.Columns>

acttextbox 类派生自用户控件,并具有事件处理程序来响应某些按键操作

private void myTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Down & myPopup.IsOpen == true)
            {
                myPopUpList.SelectedIndex = 0;
                ListBoxItem lbi = (ListBoxItem)myPopUpList.ItemContainerGenerator.ContainerFromItem(myPopUpList.SelectedItem);
                lbi.Focus();
                e.Handled = true;
            }
}

目的是当显示自动完成弹出窗口时,按下和向上允许用户浏览其内容。当控件放置在布局容器的层次结构中时,这将按预期工作;但是,当它是数据网格中单元格的一部分时,预期的行为就会丢失。看起来 DataGrid 使用 previewKeyDown 来应用它自己对向下或向上箭头的解释,虽然它没有将事件设置为已处理,但当事件到达我的控制焦点时,它会丢失,并且不同的行是选择。

我上网查遍了,找不到任何关于如何处理这个问题的线索。当然,我已经看到 DataGridTemplateColumns 中的控件处理各种输入,但我不知道它们是如何完成的。

【问题讨论】:

  • 你使用Snoop (snoopwpf.codeplex.com) 寻找事件路线了吗?也许这可以给你一个提示。
  • 这是个好主意。我将尝试确认我对正在发生的事情的理论。虽然,我认为我仍然需要对 TextBox 的默认 PreviewKeyDown 做一些事情。

标签: wpf wpfdatagrid routedevent


【解决方案1】:

好的,根据一些使用 Snoop 的建议,我知道发生了什么。事实上,问题不在于 DataGrid 正在对 PreviewKEyDown 事件做某事,而是我正在将焦点从当前正在编辑的数据网格单元格上移开,从而触发 CellEditEnding 事件。这导致了我观察到的行为。

【讨论】:

    猜你喜欢
    • 2014-04-17
    • 1970-01-01
    • 2014-03-12
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    相关资源
    最近更新 更多