[英]How to handle TextBlock.KeyDown event, when TextBlock is a part of UserControl?
我有這個簡單的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
也不會觸發。
然后在HierarchicalDataTemplate
使用此UserControl
:
<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>
從UIElement.KeyDown的文檔中:
在焦點位於此元素上並且按下鍵時發生。
您使用的TextBlock沒有焦點,因此KeyDown事件將由另一個控件處理。
您可以切換到TextBox並應用一些樣式,以使其外觀和行為類似於TextBlock,但是您將能夠獲得焦點並處理事件。
您應該使用PreviewKeyDown
事件而不是KeyDown
事件。
好的,即使這個問題是很久以前發布的,我也遇到了同樣的問題,並且找到了一種使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。 為了安全起見,通常需要在類的構造函數中執行此操作,該函數僅在類啟動后才被調用(盡管我仍然更喜歡構造函數)。
您可以使用此方法為任何事件創建事件處理程序。 只需為另一個屬性(如KeyUp,PointerMoved,PointerPressed)更改“ KeyDown”,然后將“&CLASS :: KeyPressed”更改為要在獲得相應類型的事件后立即觸發的函數的名稱。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.