Ok so there are many ways to go about fixing my problem. The title describes one.
The problem is that I have made an editor using a smart text box control (ScintillaNET) and I wish to implement an Edit -> Undo button on the menu that also displays its short-cut key in the text. Unfortunately I cannot simply bind it since it will result in the undo event being fired twice (once that the control does on its own, and once by me).
I still need the button to run the undo if it is clicked by the user (as opposed to the short-cut key).
There are 3 ways to fix this that I can see:
Unbind the key from ScintillaNET control (couldn't find out how to do this).
Find a way of identifying if the button is clicked or short-cut-keyed.
Make the appearance of a short-cut key without actually applying one.
Does anyone know how to do one of the above?
I would prefer not to override draw methods and the like.
EDIT:
I was a bit inaccurate about my question. It was actually a ToolStripMenuItem that I needed to check. Sadly it does not have a Focused property.
Found it!
I set the ShortcutKeyDisplayString in the form's constructor without actually setting a shortcut key.
public EditorForm()
{
....
undoToolStripMenuItem.ShortcutKeyDisplayString = "Ctrl+Z";
....
}
Related
I'd like to control which button is focused in my view. User must be able to perform a job without need to use mouse. And job is going through all elements. Depending on element, some buttons will appears, some disappears.
I could do it with dependency properties. To example, if there are buttons Previous and Next, then I can provide IsPreviousFocused and IsNextFocused to set focus to them after certain event. Events can be: showing window for the first time (something should have focus already), reaching 1 element (hiding Previous button, setting IsNextFocused), reaching last element (opposite), etc.
This looks reasonable more or less.
But, if I have, to example, 10 buttons (different operations), then all of them will have to have dependency property!
So I was thinking about much easier approach: when I hide button, there will be no focus
if(FocusManager.FocusedElement == null) { ... }
If I can detect, when there are no focus, then I can try to set it to one of the buttons somehow. This way, I don't really need any complicated focus management
Question is: how to deal with FocusManager.FocusedElement in MVVM scenario? How to detect when there is no focus (when window is shown first time, when certain button is clicked and become invisible, etc)?
P.S.: I actually hate ms for making another technology without thinking fully into it; focus is very basic feature (and everybody care about it in their software), but there is no direct support for it (in xaml); looks like "oh, its too complicated, lets skip it" solution.
You could control your focus from your ViewModel by using the approach shown here:
Set focus on textbox in WPF from view model (C#)
Ok. This seems like an incredibly basic use case but fore some reason I am having an issue finding a common solution across control types.
Heres the use case:
A form is presented to the user with any editable controls. (Text box, combo, grid etc.).
The user edits a value in the control and tabs out.
Expectation is that I can wire to an event like Lost Focus and do "foo" with the changed value.
The user then gives focus back to the control and tabs out without making an edit.
Expectation is that whatever event I am wired to I can check if the value has been changed.
Is there one common event across controls that will only fire when the user has finished editing( such as tab out or enter ) and allow me to check previous state vs. current state?
Jason, you may want to look into Binding and DependencyProperties in WPF instead of tracking events in your form. You would bind a class to your form which exposes properties to be changed. Using DependancyProperties a single event is fired called "PropertyChanged".
Unfortunately is is a broad topic, but you will really get the full benefit of the WPF programming model. Searches on "dependency properties in wpf" will give you some good examples.
I think maybe this is Focus issue. There exist two different focus types: keyboard focus and logical focus. The the control that has keyboard focus is the one that has the caret, in what the user press a key and the control process that input. The a control may have the logical focus but not having the keyboard focus. Please check this in the MSDN article "Input Overview". About the other question, maybe you could process the TabControl.SelectedItemChanged for taking the event when a tab item selection changed.
Hope this is helpful to you...
What you may be interested in is implementing INotifyPropertyChanging (not just INotifyPropertyChanged).
As noted in the answer of this question, the INotifyPropertyChangING does not prevent you from changing a value, but to detect WHEN something DOES change, and what it's new value is going to be.
Hope it helps in your solution needs.
As the previous answers suggested, you would be better off by implementing a view - viewmodel structure, with your viewmodel having implemented INotifyPropertyChanged, and thus allowing you to bind to properties that will announce their changes to the UI.
If you don't want to do this, you can eventually subscribe on your input elements to the PreviewKeyUp event, check if the Tab key has been pressed and proceed from there.
This seems very simple, but I can find nothing on a web concerning the behaviour I want to add to my custom control.
My custom control is a textBox with a list of choices. When the text entered by the user is not part of the list, a popup will appear with the list allowing the user to select a correct choice.
Sometimes, there may be a default button on the container in wich the custom control has been added. If so, when the enter key has been pressed, if the text is wrong, The popup must been displayed. If there is no default button, on enter, nothing must happen even if the text is wrong.
To be able to create this behaviour, I must be able to detect the presence of a defaultbutton in the container, and it must be done inside the c# code of the cutom control.
I hope the description is clear enough.
Thanks in advance
Have you thought about implementing an MVVM approach and the Command pattern? So long as your view model knows what the choices are, you can bind the default button to a command. So long as the commands CanExecute handler returns false, i.e., an appropriate choice has not been entered/selected, the button will be disabled and won't respond to the user pressing enter.
Since I was unable to know what other controls I had from the custom control I chose to go like this:
I made a recursive function to find the first parent using FrameworkElement.Parent
Having the parent, I could take a look at every controls it contains.
As soon as I saw a button, I had to verify if IsDefault.
For this one, I used the VisualTreeHelper GetChildrenCount(DependencyObject obj_Parent) and GetChild(DependencyObject obj_Parent, int childIndex). Recursivity once again...
It works very well even though it means more code to execute.
When I switch tabs with the following code
tabControl1.SelectTab("MyNextTab");
It calls the tabPage_Enter for the tab it is switching from and the tab it is switching to. I want it to be called for the tab it is switching to, but not the tab it is switching from. How would I turn this off. I do know when it happens so if there was a call I could make that would turn off calling the enter method for that tab I could implement that.
Yes, I repro if I use a button to change the selected tab. TabControl forces the focus onto itself before it changes SelectedIndex. This appears to have been done to avoid problems with the Validating event. The focus change produces the first Enter event, for the active tab, the tab change then produces the second Enter event.
Knowing this, you could set a helper boolean member, indicating that the first Enter event should be ignored. Be careful to check that the current tab isn't already the one you want to select. In a perfect world, this behavior shouldn't matter. The focus really did move to the active tab first.
Can you check the index of the active tab and workaround using that?
Wrap the code in the event within a check so it only processes when you want it to.
If you can write code to switch it off then you could write code to set a state that prevented the code in the event from running.
I have a UserControl that consists of three TextBoxes. On a form I can have one or more or my UserControl. I want to implement my own tab behavior so if the user presses Tab in the second TextBox I should only move to the third TextBox if the the second TextBox has anything entered. If nothing is entered in the second TextBox the next control of the form should get focus as per the normal tab behavior. If the user hasn't entered anything in the first or second TextBox and the presses tab there is this special case where a control on the form should be skipped.
By using the ProcessDialogKey I have managed to get it work kind of ok but I still have one problem. My question is if there is a way to detect how a WinForms control got focus since I would also like to know if the my UserControl got focus from a Tab or Shift-Tab and then do my weird stuff but if the user clicks the control I don't want to do anything special.
As a general rule, I would say overriding the standard behavior of the TAB key would be a bad idea. Maybe you can do something like disabling the 3rd text box until a valid entry is made in the 2nd text box.
Now, having said this, I've also broken this rule at the request of the customer. We made the enter key function like the tab key, where the enter key would save the value in a text field, and advance the cursor to the next field.
I don't think there's a built-in way that you could do it. All of the WinForms focus events (GotFocus,LostFocus,Enter,Leave) are called with empty EventArgs parameters, which will not give you any additional information.
Personally, I would disable the third textbox, as Rob Thomas said. If you're determined to do this, though, it wouldn't be difficult to set up a manual (read: hackish) solution. Once the tab key is pressed (if the focus is on the second textbox), set a variable inside your form. If the next object focused is then the third textbox, then you know exactly how it happened.
The reason for this odd tab behavior is all about speed in the input process. It was really good to get some input, I hadn't thought about disabling a textbox but that could actually work. But using the Enter key to accept the input hadn't even crossed my mind. That will work so much better. The user can enter the numbers and then press enter to accept the input and the next possible textbox will be the active one. It's like having the cake and eating it too, The speed factor is there since when using the enter key no unnecessary tabing must be done to get to the correct field and using the enter key next to the numeric keyboard makes it really smooth.
Thanks for the input!
I agree with DannySmurf. Messing with the tab order might give you hell later on if the requirements for the application change.
Another thing that you could do is to implement some kind of wizard for the user to go through.
Better than disabling controls, try monkeying around with TabStop - if this is false, the control will be simply skipped when tabbing.
I'd also suggest that the Changed event of the TextBox is the place to be updating TabStop on the other controls.
I've done something similar to this with a login control, where users could enter either a username or an email address (in separate fields), plus their password, and tabStop is what I used to get the job done.