KeyDown Events in WPF Application only work with Focus - c#

I have a calculator with a WPF Interface, and there is a grid containing most of the buttons. I want these buttons to react to, say, the NumPad keys, among others. I created KeyDown Events for all of them, but this only works when the button whose key I press is currently focused. I read about the KeyPreview property, but that only exists for Windows Forms, correct? I feel like I just need to change a property of my ButtonGrid, but I can't figure it out.
Relatively new to programming by the way.
Edit: This is one of the methods, how would a generic method look like? OnlyDigitsInTextBox is a custom method consisting of the .AppendText Extension method.
private void Button6_Key(object sender, KeyEventArgs e)
{
if (e.Key == Key.NumPad6)
{
OnlyDigitsInTextBox("6");
}
}

Best approach would be to use Custom Commands with KeyBindings.
WPF Custom Commands
WPF KeyBindings

I made it work now with an EventHandler using switch case for every possible button, and putting that EventHandler up as a property of the MainWindow, setting the Focusable property of all buttons to False. This is probably far from ideal, but it works for now, so thanks everybody!

Related

How to know which button has been pressed when you have a generic buttonclicked event?

I havent been able to think of the right wording for this question so apologies if its confusing.
I'm writing a program that will give a user an ability to send hex commands over serial for a number of custom object types.
I have 8 buttons on the XAML menu page each one representing each object and I have my C# buttonclick event that does its thing when one of the buttons is clicked but I need to be able to know which button is clicked without having to write a method of each individual button.
This is due to the user having the ability to create additional buttons dynamically.
How can I tell the buttonclicked event which of the buttons (1-8 etc) has been pressed?
<Button Content="Button!" Click="OnButtonClick" Command="{Binding WhateverCommand}" />
private void OnButtonClick(object sender, RoutedEventArgs e)
{
Button b = e.Source as Button; //Here you can get which button is clicked
}
The answer from David is one possible solution. But I'm not sure what you are doing then? What should happen then? Is it depends on Button Name (Content), or something else?
Without knowing your exactly problem I would nevertheless prefer the MVVM pattern based solution.
I would do an ObservableCollection of SomeActionViewModel which have a ICommand property and bind that property in XAML-Template Command={Binding MyCommand}. I whould bind the ObservableCollection to some ItemsControl and template it to display buttons
Here is a similar problem with MVVM example
https://social.msdn.microsoft.com/Forums/en-US/2cf2757c-e2a1-4b93-b130-6d900b1359ea/how-to-bind-a-different-command-to-each-dynamic-button-in-c?forum=wpf

C#: KeyDown Event does not work in controls

I am trying to finish my final school project. I am creating a c# winform game to be specific. We can not use anything else.
I will not be posting here code because I got it pretty messed up and I guess u can answer me just with this info.
Setup:
I got my program set up like this. The is main form and two user controls. I switch those controls within the main form during the game. The first one is MENU and the second one is GUI with picturebox acting as a gamescene.
Problem:
Setup quite not important I guess. But what I need to do is to do some action when I press key Down on the first Control (while it is active in the form). Sounds easy I thought at first but the onKeyDown event in the menu.cs(1st usercontrol) is doing nothing when i press the key(The event method is not blank). I tried this.previewKey = true; in the menu load method but it did not even recognize it.
So my question is: Is there any way to use onKeyDown in usercontrols code?
I did it this way becouse I use the same keys in the second controls and i didnt want it to get messy (which obviously did the oposite huh)
TLDR: Need to use onKeyDown event in userControls (keyPreview might be the key)
BONUS
I also need to somehow link variables from Controls 1 to Form and Controls 2.
I looked it up and found out it would be easy in situacion like "Form to Form" but since it is userControls I cant figure it out and I feel like I am just a tiny bit from finishing it.(feels terrible sitting here 9 hours xD please help)
On the keypress event make sure it is for the selected control an not the main form. If you are capturing for the form to determine which key was pressed then use the keypress event for that. You can use a messagebox to verify that you have the right control. Every key has an integer value and you can access and use those by using the properties of e.
Bonus. Depending on how you implemented your code you will have to use either global varibles to pass the data across the forms or use delegates to actively access and set controls on another form
You have to register the event in the Form.Designer.cs :
private void InitializeComponent()
{
// Your form properties here
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
}
You're KeyDown event can be used like this in the Form.cs code :
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
// To know if your event is working and the value of the key who's pressed
MessageBox.Show("Key Pressed = "
+ e.KeyCode.ToString()
+ ", Value = "
+ e.KeyValue.ToString());
// Example - add some actions bellow
if (e.KeyValue == 13)
MessageBox.Show("Return Key Pressed");
}

How to check whether text input is finished

I'm developing a simple WPF application where I want to use the text changed method for a specific text field. the thing is I implemented the method but, the method gets fired in very short period, like even after i enter one character. I want to check whether the text change is completed in order to go with the methods written in the text changed method.
private void searchBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (...) // how to check whether the typing is finished?
{
// code goes here
}
}
I think you'll need the LostFocus event for this. As #SLaks comment says, you can't predict whether the user will press another key. Alternatively, you could databind the control - depending on what you're actually trying to do that may make more sense.
Instead of TextChanged, try monitoring the LostFocus event, which will fire when the user has left the textbox, either through pressing Enter/Tab or clicking somewhere else on the form.
Agree with LostFocus
UIElement.LostFocus Event
Question does not ask about binding but something to consider.
In binding the equivalent is UpdateSourceTrigger="LostFocus"
Binding.UpdateSourceTrigger Property
With binding you can get into more advanced validation UI effects.
How to: Implement Binding Validation

Equivalent of 'KeyPreview' property in WinRT Metro

I am writing a metro app where it makes sense for focus to jump to a single text box anytime the user starts typing. But I can't figure out how to implement this functionality locally, without modifying other user controls to detect keydown and forward focus to the text box.
In WinForms I would have used the form's "KeyPreview" property, which caused any key presses within the form's controls to fire form KeyDown/KeyPress/KeyUp events. I can't find any equivalent in metro.
I tried the naive solution of just forcing focus to the text box anytime it left, but that has obvious problems (e.g. buttons flicker instead of staying highlighted when you click and hold on them).
How can I ensure any keyboard typing goes to a specific text box?
The event needs to be placed on the current core window, which is the root element all controls are nested on.
Windows.UI.Xaml.Window.Current.CoreWindow.KeyDown += (sender, arg) => {
// invoked anytime a key is pressed down, independent of focus
}
Here you go ...
Responding to keyboard input (Metro style apps using C#/VB/C++ and XAML)
&&
Implementing keyboard accessibility (Metro style apps using C#/VB/C++ and XAML)
Pay special attention to routed events. There are examples there too.
Hope this helps.
In your xaml code u bind these to events to page::
Loaded="pageRoot_Loaded_1"
Unloaded="pageRoot_Unloaded_1"
and inside these methods u have to bind and unbind ur events for keydown or keypress
private void pageRoot_Loaded_1(object sender, RoutedEventArgs e)
{
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
}
private void pageRoot_Unloaded_1(object sender, RoutedEventArgs e)
{
Window.Current.CoreWindow.KeyDown -= CoreWindow_KeyDown;
}

WPF internal : Why UserControl is overriding AdjustBranchSource?

By Using reflector you can see that WPF UserControl is overriding AdjustBranchSource.
internal override void AdjustBranchSource(RoutedEventArgs e)
{
e.Source = this;
}
My very own problem regards inconsistency caused by that issue.
When an element is based inside a user control or outside. The Source parameter behaves differently. Which surprises me the source should always be the element in target by the RoutedEvent.
The question is why was it implemented like that?
This kinda makes sense. If you treat the UserControl as a black box then you shouldn't know what controls are on it, and thus the source of an event.
If you need to distinguish between different buttons on the UserControl then the UserControl should have it's own events which the buttons trigger. That way from the outside it looks like the right event and the user of the UserControl doesn't need to know which button did which event.
To give an example, on a listbox, do you need to know that the down-scroll button was the button that sent the original event? Or do you just need to know that a scroll-down event was triggered.
The source of a routed event can change throughout the routing of the event. I'm not entirely sure why UserControl changes it, but can you not just use the OriginalSource property on RoutedEventArgs instead?

Categories

Resources