如何在WPF中单击按钮单击按键事件 [英] How to fire a Key Press event of a Key on button click in WPF

查看:81
本文介绍了如何在WPF中单击按钮单击按键事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个触摸屏应用程序,我必须提供键盘控制。为此,我需要触发所有键的按键事件,我将显示为按钮。



目前我正在使用此代码,

I a developing a touchscreen application where I have to give a keyboard control. For that I need to fire the key press event of all keys which i will be showing as button.

Currently i am using this code,

var key = Key.A;                    // Key to send
           var target = txtUserName;    // Target element
           var routedEvent = Keyboard.KeyDownEvent; // Event to send

            target.RaiseEvent(new System.Windows.Input.KeyEventArgs(Keyboard.PrimaryDevice,
            Keyboard.PrimaryDevice.ActiveSource, 0, key) { RoutedEvent = routedEvent });





我在google搜索后得到的,我点击了按钮点击这一点但没有发生任何事情。



请帮助..



谢谢



Which i got after googling, I have written this on button click but nothing happening.

Please help..

Thanks

推荐答案

感谢您的所有澄清。

Thank you for all your clarifications.
在我的答案的先前版本中,我写道:
In previous version of my answer, I wrote:

如果您已经有做到了,对不起干眼。但是,请执行以下操作:提供100%自包含的项目代码,以显示所需的效果,即使它不起作用。尽可能小。您甚至不需要使用任何XAML,甚至不需要使用项目文件。您可以使用显式Application.Run调用只将其与一个文件匹配,并在代码中添加一个或两个UI元素。它会给你很小的代码。描述你对它的期望和你得到的东西,为什么你觉得它是错的。

If you already have done that, sorry for the dry shot. But then, do the following: provide 100% self-contained project code demonstrating the desired effect, even if it does not work. Make it as small as possible. You don't even need to use any XAML and not even project file. You could fit it to just one file with explicit Application.Run call and just one or two UI elements added in code. It will give you really small code. Describe what you expect from it and what you get instead, why do you feel it's wrong.

现在,我将尝试演示它。到目前为止,我没有重现 RaiseEvent 的效果来发送一个角色。然后我意识到1)你真的不需要它,2)它无论如何也无济于事(但计划稍后再深入研究)。



所有你的努力集中在模拟仅一个目标上的输入,这是你的文本框,根据你的澄清,这不是你的最终目标。此外,仅仅为UI编程使用事件的模拟被认为是邪恶的;在许多文章中,人们提出了非常有说服力的论据。请参阅我的评论,其中列出了一些应排除的情况。不过,让我们先实现它,以说明如何只使用一个应用程序:

Now, I'll try to demonstrate it. To present moment, I failed to reproduce the effect of RaiseEvent to send a character. Then I realized that 1) you don't really need it, 2) it would not help you anyway (but plan to dig into this later).

All your effort was concentrated on simulation of the input on only one target, which is your text box, and, according to your clarification, this is not your final goal. Moreover, using emulation of the events just for UI programming is considered evil; in a number of articles people provided very convinced arguments against that. Please see my comments where I listed some cases where the exclusion should be made. Nevertheless, let's fist implement it, to illustrate how it can be done with just one application:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

class MainWindow : Window {
    const char demoFrom = 'A';
    const char demoTo = 'F';
    internal MainWindow() {
        this.SizeToContent = SizeToContent.Height;
        this.Width = 200;
        StackPanel panel = new StackPanel();
        this.Content = panel;
        TextBox textBox = new TextBox();
        panel.Children.Add(textBox);
        for (char index = demoFrom; index <= demoTo; ++index) {
            Button button = new Button();
            button.Content = (char)index;
            panel.Children.Add(button);
            button.Click += (sender, eventArgs) => {
                Button senderButton = (Button)sender;
                char toSend = (char)senderButton.Content;
                textBox.SelectedText = string.Empty + toSend;
            };
        } //loop
    } //Main Window
} //class MainWindow

class TheApplication : Application {
    protected override void OnStartup(StartupEventArgs e) {
        this.ShutdownMode = ShutdownMode.OnMainWindowClose;
        MainWindow = new MainWindow();
        MainWindow.Title = "Keyboard Test";
        MainWindow.Show();
    } //OnStartup
    [STAThread]
    static void Main(string[] args) {
        Application app = new TheApplication();
        app.Run();
    } //Main
} //class TheApplication



当然,你还需要添加箭头键,删除,退格和其他可能的东西。至于大写和移位,我已经建议你把它作为键盘内部,只是内部操作模式。你应该简单地修改你发送的角色,但你的代码应该只发送一个角色,没有别的(但你可以选择一次发送一些字符串)。



To将此源代码构建为项目,您可以从模板创建WPF项目(这只是为了消除保留WPF引用的程序集),然后删除每个文件并仅添加一个带有上述内容的文件。这是一个单文件解决方案。或者,您可以从空项目开始并添加WPF引用。



现在,由于您的目标是创建系统范围的虚拟键盘,这是一个完全不同的故事。我应该得到一个单独的答案。我只需要更多时间。



-SA


寻找SendKeys-方法。

有了这个你就可以发送一个按键点击的KeyCode ...



根据谢尔盖的建议 - 这段代码-snipped在已知类中启动一个know方法:

Look for the SendKeys-Method.
With this you could send a KeyCode with a Button-Click ...

Based on the suggestion of Sergey - this code-snipped starts a know method in a known class :
System.Reflection.MethodInfo onKeyDown = YourTextBoxInstance.GetType().GetMethod("OnKeyDown, new object[] { new KeyEventArgs(YourKey) });



在这种情况下,KeyEventArgs应该包含有关(模拟)密钥的信息。



我必须说这个想法非常好,因为我的解决方案使用SendKeys-方法...;)


in this case the KeyEventArgs should contain the Information about the (simulated) Key.

I must say that this idea is very much better as my solution with the SendKeys-Method ... ;)


在我的回答中,我使用 RaiseEvent 忽略了你的代码示例,并且从未正确解释它的错误但你可能需要了解它。



我终于试图重现提升事件的使用,并最终意识到为什么你看到没有发生任何事情的结果。



答案是:它确实有效。它完成了预期的目的:它确实引发了指定目标上的指定事件。因此,将调用添加到目标事件实例的调用列表中的所有事件处理程序。这是 RaiseEvent 的真正效果。如果您订阅了一个或多个键盘事件,这很容易检查 - 我只是尝试过,它可以工作。



唯一的问题是:你不能使用用于模拟通常的,例如,响应键盘操作的文本框行为,例如添加或删除字符。它仅与响应硬件事件而触发的事件有关。处理键盘事件时,低级键盘事件已经发生,即使您没有订阅,也会发生处理(导致,比如在文本框中添加字符)对任何事件。你只能得到关于此的通知(为了做别的),或者非常重要的是,你可以通过分配 eventArgs.Handled = false来阻止事件处理; 之间调用 UIElement.KeyDown 之类的事件只是为了让您有机会获得通知和/或修改行为。 (在这样的考虑中,你不应该将事件混淆为某种类型的成员,事件实例和事件作为系统状态变化的动态行为。)



RaiseEvent 只是为您提供另一种方法来筹集这些 UIElement 事件。请注意,不允许在任何代码位置的任何事件实例上调用事件调用,但声明类中的代码除外。 RaiseEvent 为您提供后门,仅适用于班级 UIElement



结论:没有办法使用 RaiseEvent 来模拟键盘动作。解决方案3中介绍了这样做的方法。



-SA
In my answers, I ignored your code sample using RaiseEvent and never properly explained what was wrong with it. But you probably need to understand it.

I finally tried to reproduce the use of raising event and finally realized why you see "nothing happening" as a result.

The answer is: it actually does work. It does what's intended: it really raises the specified event on the specified target. As a result, all the event handlers added to the invocation list of the event instance of the target are invoked. This is the real effect of RaiseEvent. This is easy to check up if you subscribe to one or more of keyboard events — I just tried it, and it works.

The only problem is: you cannot use is to simulate the usual, for example, text box behavior in response to the keyboard action, such as adding or removing characters. It is only related to the events fired in response to the hardware events. When you handle your keyboard event, the low-level keyboard event has already happened, and it's handling (resulting in, say, adding a character to the text box) will happen even if you don't subscribe to any events. You can only get the notification on this (in order to do something else), or, very importantly, you can block event handling by assigning eventArgs.Handled = false; the events like UIElement.KeyDown are invoked in between just to give you this opportunity to get notification and/or modify the behavior. (In such considerations, you should not mix up the event as the member of some type, the event instance and event as the dynamic act of the change of the system state.)

RaiseEvent just gives you another way to raise these UIElement events. Note that it is not allowed to call event Invoke on any event instance from any place of code, except the code which is placed in the declaring class. RaiseEvent gives you a back door, just for the class UIElement.

Conclusion: there is no a way to use RaiseEvent to emulate the keyboard action. The way to do so is described in Solution 3.

—SA


这篇关于如何在WPF中单击按钮单击按键事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆