Modify element property on key press - c#

I need to hook up an event that shows a WPF Popup control when a TextBox has focus and a keyboard shortcut is clicked. For instance. When typing in the TextBox field, the user can press ALT+H for help, to get a popup dialog showing input help. Pressing ALT+H "outside" the TextBox should not open the popup.
Any ideas?

Looks like a job for an Attached Event.
From MSDN:
The concept of
an attached event enables you to add a handler for a particular event
to an arbitrary element rather than to an element that actually
defines or inherits the event. In this case, neither the object
potentially raising the event nor the destination handling instance
defines or otherwise "owns" the event.
You can find details here, on the MSDN

Use command binding:
ApplicationCommands.Help.InputGestures.Add(new KeyGesture(Key.H, ModifierKeys.Alt));
this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Help, Help_Executed, Help_Enabled));
In function Help_Executed do some operations
In function Help_Enabled check if textbox selected, do e.CanExecute = true;
InputGestures assign ALT-H for help

Related

VisibleChanged don't raise when not visible

I'm working on c# WinForm.
I have an custom UserControl : MyControl : UserControl, INotifyPropertyChanged. I attached a method on event on event VisibleChanged : this.VisibleChanged += new System.EventHandler(this.MyControl_VisibleChanged);
My application have some pages, each page is a control like MyControl. Top of MainWindows contains Button, used to switch tab.
My problem is that my function MyControl_VisibleChanged is called only when Visible is changing to true. I added a test in a tab to check MyControl.Visible, when I select the other tab, MyControl.Visible is false but no event is raised.
I've try to define a new property Visible for this control but value is never set, only the base value is modify.
Can you help me to find a solution ?
This is a quirk in the way Visible works, explained here. His solution was to use properties that he has complete control over, but you could instead have a method allowing the tab switches to tell their children to raise their VisibleChanged event that extra time.
The first two answers to this question may also be useful.

ContextMenuStrip - Prevent item-selection by key-press

When a ContextMenuStrip is open with, say, an option for Copy - if the user presses C - Copy is selected.
How can this be prevented?
If setting the KeyPressEventArgs.Handled field doesn't do the trick, you may need to catch the PreviewKeyDown event and change the event to not be an input key (PreviewKeyDownEventArgs.IsInputKey = false) to prevent it from ever getting treated as a regular KeyDown/KeyUp/KeyPress.
See http://msdn.microsoft.com/en-us/library/vstudio/system.windows.forms.control.previewkeydown(v=vs.110).aspx for further details.
Note: you'll also have to move all your KeyPress-handling code into PreviewKeyDown, because you'll stop getting the KeyPress event when you set IsInputKey to false.

textbox not losing focus

I have a Form which covers the entire screen. I have a textbox on it which is normally hidden but appears when a user clicks, drags mouse and then leaves. After that user can enter any value in the text box. Once entered, ideally user should be able to click outside of textbox and then the normal service should resume.
By normal service I mean that form should start getting all the events. What I have done so far is that on TextBox's KeyDown event; when Escape key is pressed, I have set the focus to the main form like this:
this.Focus(); //where this is mainform.
But this doesn't seem to work since Textbox still keeps receiving all the keys. I have a KeyDown event handler both for Form and Textbox and I have checked that all the KeyDown events pass on to the TextBox. I have a TextBox Leave event Handler as well which never gets called.
This TextBox is the only control on the form and the main form is used for drawing shapes (if that matters).
So, how can I make this TextBox lose focus when user clicks outside of it.
if it works like in VB, for what I remember, try to set the form property KeyPreview to false so all keys will be passed only to the focused control on the form.
If you set your form KeyPreview property to true, your form has first chance to handle any keystrokes that you make. If it is something you want to handle i.e. escape as in your comment above, handle it in your form's KeyDownEvent and mark it as handled so your textbox will not see it.
From above Msdn Page:
When this property is set to true, the form will receive all KeyPress, KeyDown, and KeyUp events. After the form's event handlers have completed processing the keystroke, the keystroke is then assigned to the control with focus.
I guess back in '11 this didn't work, but now
this.ActiveControl = null;
works fine. However if you intend to use Tab to cycle controls, focusing a label with suitable TabIndex is the way.

Cannot set button.IsEnabled=true in C# WPF

This question is as simple as it sounds. Assume button.IsEnabled == false, when I execute button.IsEnabled = true; the button remains false!! (By using the Visual Studio 'watch' feature to immediately look at the value after setting it in the debugger)
Obviously, this is not a common occurrence as generally that code works. But there is obviously something in the system that is blocking the setting and I am looking for ideas about what it could be. At first I thought it was because the button was hooked into an ICommand, which obviously controls the IsEnabled setting itself. So I eliminated the ICommand. That worked for a different button but this button is not hooked to an ICommand via "Command={Binding Path...}". In fact this button is created in C# as simply:
Button button = new Button();
button.Content = "Save Record";
button.IsTabStop = false;
These buttons exist in a Custom Control toolbar and the code which is trying to set their value occurs in a PropertyChanged eventhandler I have written. Curiously the same code initially successfully sets the button to false and that works! What could possibly be prohibiting setting IsEnabled=true?
A few hours later:
Bah, rookie mistake (after 35 years in IT). Further on down in the code was the line:
button.Command = new myCommand(...);
So, in fact, the button was hooked up via a Command Interface. I took that out and replaced it with a button click eventhandler and the problem is solved. Since I could not find this issue in Google, after numerous searches, let me restate the problem in case others encounter it: when you hook up an ICommand to a UIElement, e.g. button, menuitem, etc. .Net takes over the IsEnabled property. You can no longer set the property programmatically.
I know you answered this, but it looks like you just ripped out the new-style code and went back to the old way. So on the off chance that you'd like to know how the new way works, read on.
Commands are a refinement of the Event system! Commands replace the IsEnabled property and the Click event, and let you define useful shortcuts to the command.
Once you hook something up to a Command, you should no longer use IsEnabled or Click for that something.
The commanding equivalent to "IsEnabled = True" is to return True from the CanExecute event handler of the Command.
Then, define an Executed handler for the Command, and this replaces the Click event.
Why is this good? Simple: You can hook up a toolbar button, a menu item, a context menu item, and perhaps some other interface parts to the Command, and you don't have to keep track of (or define) each of those elements' Properties or events. Think of a text editor application. The traditional way would be to hook up an event to Edit > Copy, the Copy toolbar button, and a context menu item; handle the TextBox's SelectionChanged event to enable/disable all of these as appropriate; and code up the Click event for each of those. The new way is: hook the command up to Edit > Copy, the Copy toolbar button, and the context menu item, define the CanExecute event to return true/false depending on the TextBox's selection property, and code the Executed handler. Looks similar? Yes, but you declare the Command connections in markup instead of code, and you don't have to write nearly as much code. It adds up to a lot of savings when you have a lot of Commands.

Toolstripbutton not validating textbox

I have a textbox, a standard button and a toolstrip containing a couple of buttons.
In the validating event of the textbox I coded to check whether it is blank.
If yes then it shows a message 'Enter Value'. When the standard button is clicked while
the textbox is empty, it's validating properly and showing the message but when the
toolstripbutton is clicked it's not validating the textbox and no message is shown. It seems that I've got to write the validation code explicitly in the
toolstripbutton_click event which is too troublesome when there are multiple textboxes and toolstripbuttons on a single form.
What I want to know is whether the textbox_validating can be fired when the toolstripbutton is clicked? Handling toolstrips is really a headache.
The ToolStripItem classes are special, they don't derive from Control. One side-effect of that is that they don't take the focus away from the active control. And that prevents the Validating event from firing.
Several things you can do. You could call the textbox' parent's ValidateChildren() method. Or you could move the focus yourself:
private void toolStripButton1_Click(object sender, EventArgs e) {
btnSave.Focus();
if (btnSave.Focused) btnSave.PerformClick();
}
Write the following in toolstripbutton click event:
Me.Validate()
You can call the textbox_validating procedure from the procedure that handles the toolstripbutton click event, but you may have to add some logic to see if it passed validation before proceeding with the rest of the toolstripbutton_click event. Since you said you have a lot of textboxes to validate, you might want to consider making a Validate() function that returns true or false and checks all of the textboxes. Then all you have to do is check if Validate() = true and call the same function from all of your toolstrip buttons instead of copying the same code over and over again.

Categories