簡體   English   中英

當TextBlock是UserControl的一部分時,如何處理TextBlock.KeyDown事件?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM