FocusManager.FocusedElement and MVVM - c#

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#)

Related

Windows 10 uwp hide soft keyboard even when I set focus to a control

I have a Windows 10 mobile uwp app and I am having two issues.
First, I set focus to controls in the app. I do this by using the common call successfully
Control.Focus(FocusState.Programmatic);
However, there are some cases where this does not work. Most times it does but for example, when my page loads, I am trying to set an initial focus in one of the fields and it does not work. I have tried this call in two places. First, in the constructor for the page, after InitializeComponenets and also in the override onNavigatedTo method. Where is the best place to call this and what are some reasons why it may not appear to work, particularly when a new page is instantiated?
Second, related to setting focus. I have a text box on my UI that I set control to with the same Programmatic focus call I listed above. However, the soft (on screen)keyboard shows when this happens. I dont want it to show up when I set focus Programmatically but then have it show if the user selects the field. The scenario is I have a barcode scanner. When the page loads, I set focus in code to the text box and it is therefore ready for me to set the text in the text box from code, based on the barcode scanner result. There is hardly ever a need for the user to type into this field. Therefore, I dont need or want to have the keyboard showing and taking up real estate. There is a rare case when I do allow them to still type the text in manually, for example, in the case the barcode does not read. They would then select the control (even though it may already have focus programmatically) which should set focus again but instead as cursor, touch or something and then I want to show the soft keyboard.
What is the best way to do this?
Thanks!
as far as focusing anything else than the TextBox did not work for me anyway, I found a good solution:
I called:
using Windows.UI.ViewManagement;
InputPane.GetForCurrentView().TryHide();
and the Keyboard gets hidden.
I think the best place to call Focus() is in Loaded event handler of the same control which you trying to focus. When this control is fully loaded, it means it's ready for interaction, including focusing.
As for preventing on-screen keyboard to appear, the TextBox class has PreventKeyboardDisplayOnProgrammaticFocus property. Try to set it to true, this should solve your issue.

TextBox LostFocus event occurs too often

I have an application in Silverlight and WPF. The error just happens in Silverlight, but same code is used in WPF.
In my application, there is a RibbonBar, with several RibbonGroups. In each RibbonGroup there are at least one RibbonButton. One of those RibbonGroups also contains four TextBox.
Every TextBox has its own OnLostFocus-Handler. When I leave a TextBox the related Handler is raised.
Now, (1) I click into one of those TextBoxes and (2) then click a RibbonButton, OnLostFocus raises and after that the RibbonButton dropdown menu appears. Everything OK.
After that, (3) I click on another RibbonButton. Again OnLostFocus raise, although - imho - it shouldn't.
So it goes on and on. After every action the TextBox keeps(or gets back, don't know) the focus and this causes the OnLostFocus-Handler to raise.
In WPF same code does not raise OnLostFocus again. Just one time, when it really lost focus.
Does anybody know, why this behaviour is that strange in Silverlight. What is really different to WPF, maybe I just have to set a property which default value ist different to WPF.
Thanks in advance.
Try using OnPreviewLostKeyboardFocus. OnLostFocus is for logical focus which you may lose for a variety reasons.
I don't know the reason for sure but I suspect that the problem you're seeing might be because the ribbon bar is in a FocusScope. When you put focus onto something inside of a focus scope then what you end up with can seem like focus bouncing around some. I'm not certain of this answer, focus is very complicated in WPF. Submitting some code samples might help.

Detecting default button on a control

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.

WP7 Complex Layout

I want to make a complex layout, and would like advice on the best way to go about this.
Here is the behaviour I'm looking for: Layout of some text blocks and some images, such that a tap anywhere on the layout will go to another related page to that item. I want a long list of this item in a scroll viewer.
First, I tried to make a grid, add the items in it, then add this grid in the outer grid, the main one for pressing, I made an event handler for mouse click, but a problem appeared; that when I try to scroll "on the item to view the all list" the event handler fired!, I tried the mouseButton up and down, and the same happen
Second, I'm not sure if it's an efficient way to make it.
I want a good way to design this complex layout, and of course it will be a programmatic way, and a way to recognize the item I press on.
It sounds like you're trying to create your own ListBox control. Using this will give you the scrolling functionality for free, and you can use the ListBox's SelectionChanged event to determine when an item has been clicked.
The best way to design the layout will depend on how complex it actually is. If it merely contains an image and some text, you should have no problem hand-coding that in XAML. If there's a lot more to it than that, I'd recommend looking into Microsoft's Blend tool. Whichever route you choose to produce the XAML, you will place the code in the ListBox's ItemTemplate, which determines how each item in the ListBox is displayed.
A good walkthrough of something similar to what you're doing can be found at http://weblogs.asp.net/psheriff/archive/2010/10/27/windows-phone-list-box-with-images.aspx

Effective way of (on a tabcontrol) tabbing through controls automatically pages through TabControl.tabs

I've tried editing this to differentiate between 'tabs' on a tabControl and 'tabbing' through controls with the tab key, but I'm just going to power through and hope the meaning is clear....
I have a c# project with an interface featuring a tabcontrol. 3 tab pages (PersonalInformation, ContactDetails, AdditionalNotes) and the relevant controls are contained within each tab.
Most of our users find it easier to navigate interfaces using the keyboard only (such as keyboard shortcuts and tabbing through controls for navigation). I've included keyboard listeners for various shortcut combinations. For example, PageUp and PageDown will allow users to page through the various tabs.
However, these users follow the same pattern for entering information: once they've tabbed through the PersonalInformation tab's controls (populating as need be) and reached the last control on the tab, they wish to 'keep tabbing'. As in: when last control focussed on TabControl.Page1, a user pressing tab will move focus to the first control on TabControl.Page2. When last control focussed on TabControl.Page2, a user pressing tab will move focus to TabControl.Page3.
In this way the information is grouped and contained together and users can simply keep typing and tabbing to enter all the information on the form, all without needing the keyboard.
So the real question is doing this effectively:
I can't just simply handle the OnLeave of the last control: a user (on the last control) selecting an earlier control (or even shift-Tab) would also fire the event.
Another problem is maintenance: Adding another control at the bottom of the tab could throw the whole thing off if the maintainer forgets/doesnt know that this 'move focus to next tab' feature. Perhaps getting the last control added to the form?
I've overridden the ProcessDialogKey method to handle the Tab (and Shift+Tab) keystrokes, shifting tabPages and focus to the relevant controls. Functionally speaking, this will work.
Maintenance issues
This particular interface doesn't change often and there's still a fair amount of usability testing underway to determine what works best before its released (so we may end up reverting).
The bad thing is that shifting focus is pretty hard-coded. I don't see any particular easy way of handling this generically.
Fortunately, maintenance should be low as there's only 3 tabPages. The business logic is completely encapsulated elsewhere so there's no risk to business functions. Code contained within relevant regions so its easy to spot. Its also a pretty quick thing to spot going wrong as the users are 'keyboard enthusiasts' and tab through everything during data entry.
Any comments/suggestions are still welcome.

Categories