Pressing tab moves to one after the next control - c#

I'm writing a simple wpf c# application for handling data in a database. A function that dynamically generates a ComboBox and a Textbox is executed from the Main TextBox when the tab-key is pressed down. Theoretically, it is supposed to switch focus to the next control, i.e. the newly generated ComboBox. Instead, when executed it moves to the latter generated TextBox. below is the code I have implemented.
Code Used:
private void Add_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
// insert generation code here
}
The above function is called when tab is pressed through this:
private void MainTextbox_KeyDown(object sender, KeyEventArgs e)
{
if(e.Key == Key.Tab)
{
Add_PreviewMouseDown(null, null);
}
}
Possible Reasons:
I think the issue might be with the time delay between the tab-key down and the process of creating the controls. Any thoughts?

Instead of writing your own key-handler, try overriding the existing one:
using System.Windows.Input;
//Later on:
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == System.Windows.Input.Key.Tab)
{
//Handle the tab key
}
}
You may, or may not need the base.OnKeyDown(e); cause that is probably what causes the default behavior of tab: Namely to shift focus to the next UI element in you application eg. the next textbox.
You could therefore try something like:
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Key != System.Windows.Input.Key.Tab)
{
base.OnKeyDown(e); //Default behavior for all other keys
}else{
//Custom behavior for the tab key
}
}
I hope this helps :-)

Related

Focus buttons with same access key instead of firing the first

Pressing Alt+B fires the first button though button 2 has the same access key.
How can I manage to focus button 1 on a first Alt+B and to focus button 2 on a second Alt+B without handling keydown event or similar?
private void button1_Click(object sender, EventArgs e)
{
System.Media.SystemSounds.Beep.Play();
}
private void button2_Click(object sender, EventArgs e)
{
System.Media.SystemSounds.Hand.Play();
}
You can override ProcessMnemonic to customize the behavior of your button when a mnemonic pressed. When processing mnemonic, when you detected the control is in the state that should execute an action based on mnemonic character, return true, otherwise return false.
In below implementation, the control first checks if the mnemonic belongs to the control, then if it is not Focuded then it calls Focus and returns true, otherwise (it's focused or it should not handle the mnemonic) returns false. This way it allows the focus move between controls with the same mnemonic:
using System.Windows.Forms;
public class MyButton:Button
{
protected override bool ProcessMnemonic(char charCode)
{
if (this.UseMnemonic && this.Enabled && this.Visible &&
Control.IsMnemonic(charCode, this.Text))
{
if (!this.Focused)
{
this.Focus();
return true;
}
}
return false;
}
}

C# Prevent Hotkeys while TextBox focus

I have a program containing multiple C# Forms TextBoxes. I've set up Hotkeys for the entire form activating certain functions. My problem is that my Hotkeys have been set onto the Form KeyDown event and they activate if I write something on a TextBox.
Example: One Hotkey might be I. Everytime I write the letter onto a textbox the Hotkey activates.
Alterior solutions and problems: I've thought about putting a Key in front of the Hotkey like CTRL+Hotkey, but these also present problems as CTRL+C is Windows Copy command etc. SHIFT is an UpperKey button.
Question: Can I prevent Hotkeys from activating when I am writing onto a TextBox without having to go through all of them in the form?
EDIT: Some code as requested. The button codes come from a stored XML file or the Hotkeys Form+Class (separate) where I've set up a window for them.
public Hotkeys hotkeysForm = new Hotkeys();
void Form1_KeyDown(object sender, KeyEventArgs e)
{
toggleInformation = hotkeysForm.toggleInformation;
if (e.Control && e.KeyCode == toggleInformation)
{
showInfo(true);
}
else if (e.KeyCode == toggleInformation)
{
if (!isInfoActive)
showInfo();
else
hideInfo();
}
}
You can disable hotkeys while texbox is an active control. Add the Enter and Leave events for all textboxes:
private void textBox_Enter(object sender, EventArgs e)
{
KeyPreview = false;
}
private void textBox_Leave(object sender, EventArgs e)
{
KeyPreview = true;
}
You should try this hack, if it could solve your problem,
Create a Extented TextBox and use it in your code. you can handle whether to write the pressed key in textbox or not in hotkeyPressed check.
public class ETextBox : System.Windows.Forms.TextBox
{
protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e)
{
if (hotKeyPressed) // this is the condition when you don't want to write in text.
{
//Do whatever you want to do in this case.
}
else
{
base.OnKeyDown(e);
}
}
}

Maintain focus on next button

Hopefully there is a pretty easy solution to this.
I have a program where the user has to click next a lot to move through a setup process.
What's the best way to maintain focus on the next button while the user enters info in text boxes?
Well, that depends on the design, but it shouldn't be a problem marking your button as "default". In winforms it's called "AcceptButton" if I'm not mistaken.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.acceptbutton%28v=VS.100%29.aspx
A way around is handling the return key for each text box. So when the user presses enter key, it can simulate pressing next button.
First move your code in the next button to a void.
private void GoNext()
{
//Do something
}
private void btnNext_Click(object sender, EventArgs e)
{
GoNext();
}
Now handle the key press.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return)
{
e.Handled = true;
GoNext();
}
}
You may also draw focus rectangle in the lost focus event of next button for visual purposes.

How to handle Copy for multiple controls when adding a ShortcutKey to menu item?

If I do not create an "Edit->Copy" menu item and assign it the shortcut keys "CTRL+C", then I can select a control (RichTextBox, DataGridView, etc..) and hit "CTRL+C" and the control itself will handle the copy. I can copy text out, and paste it into notepad, etc..
Now throughout my whole form, I have a lot of controls. But I have a custom control that I want to make clear that I handle Copy functionality for. So I added the ShortcutKey CTRL+C to Edit->Copy, and by default it is set to Enabled.
Now, I have to implement an event handler for the 'click' event on that menu item. If I explicitly put in code to handle the copy, then it works:
public void menuEditCopy_Click(object sender, EventArgs e)
{
myCustomControl.Copy();
}
However, now Copy does not work on any other type of control. My first inclination was to find out the type of control that has focus, and implement a limited set of copy code for each of them:
public void menuEditCopy_Click(object sender, EventArgs e)
{
if (this.ActiveControl is MyCustomControl)
{
((MyCustomControl)this.ActiveControl).Copy();
}
else if (this.ActiveControl is RichTextBox)
{
((RichTextBox)this.ActiveControl).Copy();
}
}
etc...
However, my controls are added to a SplitContainer, and debugging shows that this.ActiveControl is set to the splitcontainer instance, not the control, even though I know that control is selected.
So my last thought is to literally check if every control has focus:
public void menuEditCopy_Click(object sender, EventArgs e)
{
if (myCustomControl.Focused)
{
myCustomControl.Copy();
}
else if (richTextBox1.Focused)
{
richTextBox1.Copy();
}
}
I would like to avoid this if possible, it is a lot of controls, and if I add a new control, I would need to update it. Is there a better way of doing this?
Thanks
A SplitContainer implements ContainerControl, so you could check for either one and look for it's ActiveControl instead. ContainerControl is the base class, so I would go for that - you might catch another type of container as well:
private void DoCopy(Control control)
{
if(control is ContainerControl)
DoCopy(control.SelectedControl);
else if(control is MyCustomControl)
((MyCustomControl)control).Copy();
else if(control is RichTextBox)
((RichTextBox)control).Copy();
else
throw new NotSupportedException("The selected control can't copy!");
}
void menuEditCopy_Click(object sender, EventArgs e)
{
DoCopy(this.ActiveControl);
}
You could try settting the KeyPreview property of your form to true. Then you could set up a handler for the form's KeyDown event which would look like the following:
private void Form_KeyDown(object sender, KeyEventArgs e)
{
if(e.Modifiers == Keys.Control && e.KeyCode == Keys.C)
{
if (ActiveControl.GetType() == typeof(MyCustomControl))
{
((MyCustomControl)ActiveControl).Copy();
e.Handled = true;
}
}
}
Here you are specifying that you have handled the Ctrl-C event by setting the event args Handled property to true. Else, if you leave it as false, the Ctrl-C key press will be handled as per usual by each individual control.
Because we have set the KeyPreview to true the form's handler gets to see each key press before any other control that it contains and can decide to deal with the key press itself or else allow it to be handled in the same way as if the form had never previewed it.
I think as well it would be necessary to remove the short-cut key from your menu item (although you could still manually put the text "Ctrl+C" next to your menu item name) for this to work, otherwise your menu item will hijack the key stroke.

Wire _KeyDown event of textbox to a _click event of button control

I have a form with a textbox called 'tbWO.' This field is used to enter a Purchase Order Number. I also have a button control called 'btnFill.' When btnFill is clicked, it fills a dataset with a parameter from 'tbWO.'
I would like to be able to press 'ENTER' in the 'tbWO' textbox (after a Purchase Order # is entered) and have it fire the btnFill_Click event I mentioned above.
I tried with this bit of errant, badly written code - but, it's just not working properly, i.e., at all, or how I think it should work. Anyway, the code is below; in all it's glory.
private void txtWO_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
btnFill.Click += new EventHandler(btnFill_Click);
}
}
I will admit confusion on using 'new EvenHandler( ?? ). Fairly new to C# (as is probably blantantly obvious.)
Any help, links, suggestions - all are greatly appreciated.
Thanks.
Jasoomian
you could do this...
private void txtWO_KeyUp(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.Enter) {
btnFill_Click();
}
}
As a rule, I abhor mapping one event handler to another. Instead, write a separate function, and have both event handlers invoke that separate function. Something like this:
private void txtWO_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
AcceptInput();
}
}
private void btnFill_Click(object sender, EventArgs e)
{
AcceptInput();
}
private void AcceptInput()
{
// Do clever stuff here when the user presses enter
// in the field, or clicks the button.
}
Granted, you may feel differently, but it accomplishes the same thing, but with (IMO) far more readable code. But it's been my experience that criss-crossing event handlers is very sloppy and leads to maintenance headaches out the wazoo.

Categories