0

我有这个简单的UserControl

<UserControl x:Class="WPFTreeViewEditing.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBlock Text="Hello, world!" KeyDown="TextBlock_KeyDown" />
    </Grid>
</UserControl>

我想处理 TextBlock.KeyDown 事件。因此,我在代码隐藏中添加了一个事件处理程序:

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
    }

    private void TextBlock_KeyDown(object sender, KeyEventArgs e)
    {
        MessageBox.Show("Key up!");
    }
}

但它不会触发。怎么了?

更新。

PreviewKeyDown也不火。

UserControlHierarchicalDataTemplate当时使用:

<Window x:Class="WPFTreeViewEditing.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WPFTreeViewEditing"
        Title="MainWindow" Height="265" Width="419">
    <Grid>
        <TreeView ItemsSource="{Binding}">
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type local:ViewModel}" ItemsSource="{Binding Items}">
                    <local:UserControl1 />
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>
    </Grid>
</Window>
4

3 回答 3

4

UIElement.KeyDown的文档:

在焦点位于此元素上时按下某个键时发生。

您正在使用没有焦点的 TextBlock,因此您的 KeyDown 事件将由另一个控件处理。

您可以切换到 TextBox 并应用一些样式,使其外观和行为类似于 TextBlock,但您将能够获得焦点并处理事件。

于 2012-07-02T09:24:13.023 回答
0

您应该使用PreviewKeyDown事件而不是KeyDown事件。

于 2012-07-02T08:31:26.743 回答
0

好的,即使这个问题是很久以前发布的,我也遇到了同样的问题,并找到了一种让 KeyDown 事件正常工作的方法,尽管它可能不是你要找的我会发布代码来帮助未来的人同样的问题。

首先,Xaml 对象中的 KeyDown 事件处理程序只有在该对象具有焦点时才会触发。因此,您需要一个 CoreWindow 事件处理程序,它有点像同一件事,但无论什么对象或事物具有焦点,它都会始终运行。以下将是代码。

//CLASS.xaml.h
ref class CLASS{
private:
    Platform::Agile<Windows::UI::Core::CoreWindow> window;

public:
    void KeyPressed(Windows::UI::Core::CoreWindow^ Window, Windows::UI::Core::KeyEventArgs^ Args);


//CLASS.xaml.cpp
CLASS::CLASS(){
    InitializeComponent();
    window = Window::Current->CoreWindow;

    window->KeyDown += ref new TypedEventHandler
    <Windows::UI::Core::CoreWindow^, Windows::UI::Core::KeyEventArgs^>(this, &CLASS::KeyPressed);
};

void CLASS::KeyPressed(Windows::UI::Core::CoreWindow^ Window, Windows::UI::Core::KeyEventArgs^ Args){
SimpleTextBox->Text = Args->VirtualKey.ToString();
};

基本上你想要一个值来保存你的窗口并使用它来创建一个新的 TypedEventHandler。为了安全起见,您通常希望在类的构造函数中执行此操作,该函数仅在类开始时调用一次(尽管我仍然更喜欢构造函数)。

您可以使用此方法为任何事件创建事件处理程序。只需将“KeyDown”更改为另一个属性,如 KeyUp、PointerMoved、PointerPressed,并将“&CLASS::KeyPressed”更改为您希望在收到相应类型的事件时触发的函数的名称。

于 2013-07-19T01:47:21.020 回答