WPF, give keyboard focus to control that was previously collapsed - c#

I am trying to give a specific control keyboard focus during a sequence of presentation changes. Say a control was in a visibility state of hidden. In a function call I can change its visibility to visible, set the keyboard focus on it with no problems. However if the control was set to a visibility of collapsed and I try to set the visibility back to visible then set focus on it, it does not take.
Is there a process I can use to allow the control to move from a collapsed state, to a visible state and take keyboard focus?

It's probably a timing issue where the control you set to visible is not ready to accept focus yet. This can happen fairly frequently when dealing with dynamic UI changes.
You should still be able to focus your control but you'll need to queue the focus action until after the control has been properly initialized. Simply using a BeginInvoke call like shown below, should do the trick.
Dispatcher.BeginInvoke(() =>
{
//Set focus here
});

Its not a matter of the control having been initialized. This again this is an issue of transitioning visual states.
Just to close loop on this, the problem is solved by calling the control.UpdateLayout()

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.

How to avoid losing the input focus on an HTML element inside a WebView?

I'm currently trying to build a touch keyboard to be used with an UWP app. One of the solutions I came up with was to use a brokered component to call SendKeys funcitons with buttons (IsTabStop being set to false and ClickMode to Press to prevent any loss of focus from the input controls). So far, everything works (tested it on TextBoxes without any trouble).
The problem: I'm encountering some issues using the WebView control : when I click a button, the WebView keeps the focus, as expected; however, the DOM elements (such as HTML's <input> markup) lose the input focus (while still being visually selected).
I found a way to solve this by resetting the focus on the webview; but that uncovered another issue. Let's say the input element is set to select all of it's content (the string) whenever it is focused. Then, each time I click one of my buttons, the content is selected and replaced by the new letter I sent to the WebView.
So, my question is, is there any way to avoid losing the focus of the DOM object when clicking on a XAML button?
NB : I do know about the InputPane, but I can't use it for this app (due to some restrictions on the client side). Also, let me know if something is unclear, and I'll edit asap.
NB2 : I have absolutely no access to the source code of the pages that will be displayed by the WebView, nor can I rely on the presence of a specific element.
The Anniversary Update introduced a new property FrameworkElement.AllowFocusOnInteraction for this scenario. Set it to false on your Button and the Button won't take the focus when it is clicked. The focus will stay on the WebView and the selection shouldn't get cleared (if not there's something else going on as well).
Prior to this there wasn't a good solution. The least bad I've seen was to call WebView.Focus() in the Button.Click handler to return the focus, then wait for the focus events to complete before proceeding in the Click hander.
If you need to target earlier systems than the Anniversary Update then you'll need to set AllowFocusOnInteraction from code after checking that it exists with ApiInformation.IsPropertyPresent . You can't do this directly in Xaml, but you can wrap the check in an attached property which can be called from Xaml. See my blog entry ComboBox on a Flyout attached to an AppBarButton loses mouse input on 1607 for sample code.

Telerik Tab Control - Only the currently SelectedPage shows controls visibility correctly

I'm using the 2013 Q3 Telerik Tab control in a C# WinForms project. If I test the .Visible property of a control placed on a Page in the Tab then it will always return false unless I Select the page. Is there another property besides .Visible that can be used to test the Visibility of a control on a Page without having to select it?
Here's my dilatation:
You should not change the native meaning of the control's properties. Period. I asked in a comment what were you trying to achieve, because I suspected that you're basing some UI logic on some control's visibility, which in my opinion isn't too good approach. The visibility should be bound to the background logic, not the oposite. You're hiding controls for some reason, because at some point something happened - so keep track of that "something" instead of inspecting its results. IMO the Visibility property should be set, but never checked.
Alternatively if it's not possible to change the concept for some reason, as a workaround I'd attach a handler to the VisibleChanged event and set Enabled property if the sender is not a tab control - then by checking against Enabled property you'd know whether the control is in use or not. I find it difficult to imagine a situation in which I'd need to check whether a control is visible.

How to check absolute control visibility and how to be notified for changes of absolute visibility

I have several controls inside my form and I perform several changes (Text, Font, BackColor etc.) on these controls. My changes are necessary only if the controls are visible. So, I want to stop performing my changes on controls that are not visible. I want to keep changing my controls when they become visible again.
I can use Control.Visible and Control.VisibleChanged, however they are not satisfactory for my purpose.
The problem is, VisibleChanged is not fired when control becomes invisible due to its parent (i.e. because its parent became invisible). Interestingly, it is fired when control becomes visible again.
Is there a way to be notified for visibility changes without recursively listening parent visibility changes?
I also want to be notified when another form is placed over my form and some of my controls become non-visible. I call this absolute visibility. (Is there another term for it?) Is there an event that I can use for this purpose?
Thanks.
You could set up a timer that checks the state of the .Visible property on the control and fire an event when that changes.

Handling selected objects on the GUI in WPF

I've built several user controls in WPF and they all get added to a canvas. I want to add a behaviour that keep tracks of the currently selected usercontrol. A usercontrol should be selected when:
The mouse clicks on it;
when it recieve focus;
when either of the two above happens to a subcontrol of the usercontrol.
Is there any way to handle this purely by using the focus mechanism of WPF or will I need to take care of this myself with assistance of the focus classes?
I've read up upon the new way of handling focus in WPF, and the problem I'm facing is that the keyboard focus determines what the currently selected object is, but some parts of the my control can't recieve keyboard focus so even though these parts are clicked, the usercontrol doesn't recieve focus.
I'm looking for advice on how to implement this feature and how much I could/should rely on the focus mecanisms. Ultimatively I wouldn't mind if only a single object could be selected, but if it's easily extendable to multi-select then I wouldn't mind this either.
Just to clarify, I know I could build this manually by handling a lot of events and keeping track of states, but I was just hoping an easier approach was available.
Combine UIElement.IsKeyboardFocusWithin with a PreviewMouseDown handler:
When PreviewMouseDown is called, set a flag and schedule callback using Dispatcher.BeginInvoke at DispatcherPriority.Input to set focus to the UserControl if the flag is still set.
Set a handler for UIElement.IsKeyboardFocusWithin property changes in your UserControl. When the handler fires, clear the flag.
The idea here is that if you click anywhere on the UserControl and keyboard focus does not result in the focus being moved into the UserControl, force it into the UserControl.
FYI, here's roughtly what step 1 looks like in code:
public override OnPreviewMouseDown(MouseButtonEventArgs e)
{
_mouseClickedButNoFocus = true;
Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
{
if(_mouseClickedButNoFocus)
Focus();
});
}
You could use the UIElement.IsKeyboardFocusWithin property, which is true when the UIElement or one of its children has keyboard focus. It is a dependency property, so you can easily use it for a trigger in a style
You can set the logical focus to the control when any of the child gets the keyboard focus using FocusManager.IsFocusScope="True". Setting the keyboard focus to the control or trying to do will eat the keys for the child controls.
You can use UIElement.IsKeyboardFocusWithin to set the focus of the control if any of the children has focus.
You can read this article which I think describes the difference between Logical and Keyboard focus quite well:
http://www.pluralsight.com/community/blogs/eburke/archive/2009/03/18/why-is-focus-in-wpf-so-tricky-managing-and-understanding-focus-in-a-wpf-application.aspx

Categories