2012-07-02 63 views
0

我有這個簡單的UserControl如何處理TextBlock.KeyDown事件,當TextBlock是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!"); 
    } 
} 

但它不會觸發。怎麼了?

UPDATE。

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

從文檔UIElement.KeyDown

發生當按下鍵時焦點是此元件上。

您正在使用沒有焦點的TextBlock,因此您的KeyDown事件將由另一個控件處理。

您可以切換到TextBox並應用某些樣式,以使其看起來和行爲類似於TextBlock,但您將能夠獲得焦點並處理該事件。

+0

聽起來很合理。我錯過了,謝謝。 – Dennis

0

您應該使用PreviewKeyDown事件,而不是KeyDown事件。

+0

結果相同。它不會着火。更新了問題。 – Dennis

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」更改爲在獲得相應類型的事件時要觸發的函數的名稱。

相關問題