I want to set the focus to a control within an application without giving focus to the whole application.
For example: Click a button which takes a while to load a screen, when the screen is loaded set the focus on one of the controls. In the meantime I have gone to a different application to do something and the focus returns to the previous application.
This happens when I use Keyboard focus or Logical focus.
Is there any way to stop this happening?
Here is the code:
private void SetFocusInternal()
{
// Focus the first control we find with the 'PositionCursor' indicator expression
FrameworkElement controlToFocus = GetFirstRequiresFocusControl();
// Give focus back to the control which last had it (if any)
if (controlToFocus == null)
controlToFocus = GetLastFocusedControl();
// Just focus the first thing we can find
if (controlToFocus == null)
controlToFocus = GetFirstFocusableControl();
// Using any of the following goes wrong!!
controlToFocus.Focus();
Keyboard.Focus(controlToFocus);
FocusManager.SetFocusedElement(FocusManager.GetFocusScope(this), controlToFocus);
}
Related
I am facing an unexpected behavior of Keyboard showing and hiding in UWP app working on tablet with windows 10.
After carefully testing again and again i noticed that this issue comes when you have focus on input box and keyboard is opened for it. Now focusing next input needs layout adjustment so that it should not be hidden by keyboard. When you try to focus next element, by default previously opened keyboard hides and now i'm not able to open keyboard un till this new input box lose focus and manually gain focus again.
So for controlling this issue i want to prevent automatic hide and show of keyboard every time i switch focus to new textbox. It should open keyboard once the page load (already found solution using InputPane) and hiding should only be by clicking cancel (x) button.
Please check this video for clearly understanding the issue.
https://www.dropbox.com/s/1c876uwytywio1t/Soft%20Keyboard%20Issue.mp4?dl=0
Please vote this suggestion if anyone else is also facing this issue.
https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/34170142-inputpane-does-not-open-when-focus-is-shifted-to-n
This issue has been partially resolved in windows 10 version 1803 released on 30th April, 2018. In this version InputPane does not hide and show again and again when focus is shifted from one input element to other.
You may try to put a horizontal-stretched placeholder control (let say, StackPanel) at the bottom of your page, then let it the same size the on-screen keyboard does. That could prevent uncontrolled auto-hide trigger being fired (at least I did that trick on UWP mobile app):
// on the window initialization, remember the input pane
this._inputPane = InputPane.GetForCurrentView()
// then, subscribe to the events
_inputPane.Showing = (sender, args) =>
{
args.EnsuredFocusedElementInView = true; // skip default vertical-shift behavior
this._placeholderPane.Height = args.OccludedRect.Height;
}
_inputPane.Hiding = (sender, args) =>
{
this._placeholderPane.Height = 0;
}
Hope it helps on the Win10 desktop same way as it was on mobile one.
P.S. Yes, initially the placeholder pane is zero-height and collapsed.
I've created a class that inherits from Combobox, the class is editable. When a user have searched for a given predicate, I want them to be able to iterate the list with pressing the down key. This is somewhat implemented as it works sporadically. Is it any way to force focus to the popup element? I would like to do this by code, and not in XAML.
I've tried
var popup = Template.FindName("PART_Popup", this) as Popup;
popup.Focus();
Which return false as expected as this didn't work.
I've also tried
var s1 = Keyboard.FocusedElement;
if (s1 is FrameworkElement)
{
((FrameworkElement)s1).MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
But this focus on the next element in the TAB stack.
This focus approach didn't work either,
Keyboard.Focus(popup);
Edit:
I solved (achieved the desired effect) by setting the animation to .None, and then close followed by open the popup again.
I have a WinForms application. Each form and user control sets up its tooltips as follows:
// in the control constructor
var toolTip = new ToolTip();
this.Disposed += (o, e) => toolTip.Dispose();
toolTip.SetToolTip(this.someButton, "...");
toolTip.SetToolTip(this.someCheckBox, "...");
...
However, the tooltips don't appear when I hover over the controls. Is this an appropriate way to use tooltips? Is there something that could be happening in another part of the application (e. g. listening to some event) that would stop tooltips from working?
Note that tooltips on my outer form's toolstrip buttons (which are configured via the button's tooltip property) do work as expected.
EDIT:
I've observed this more and I've noticed that sometimes the tooltip does show up, it is just extremely "flaky". Basically, sometimes when I mouse over a control it will show up very briefly and then flicker away. I can get it to show manually with .Show() and a long AutoPopDelay, but then it never disappears!
Your code seems ok to me. I couldnt find anything wrong in your code. But, it could be failed only when control is disabled. BTW, you can try another method like this. but, i would not like to suggest you to show the tooltip like this.
private void someButton_MouseEnter(...)
{
toolTip.Show("Tooltip text goes here", (Button)sender);
}
You can also assign the location where tooltip should be displayed in .Show() method. there are some overloaded function that you can use. Read the msdn for more information about ToolTip.Show() method.
I faced similar issue when my tooltip was not showing up over the RichTextBox once in about 3-5 times it normally should. Even forcing it to show explicitly with toolTip.Show didn't help. Until I changed to the way mentioned by Shell - you have to tell where you want your tooltip to appear:
'Dim pnt As Point
pnt = control.PointToClient(Cursor.Position)
pnt.X += 10 ' Give a little offset
pnt.Y += 10 ' so tooltip will look neat
toolTip.Show(text, control, pnt)
This way my tooltip always appears when and where expected.
Good luck!
I wrote the following method to "propagate" ToolTips from parent controls (that have a tool tip set) to its child controls (unless they have their own overriding ToolTip).
It's designed to be dropped into the form or control you're starting with, but it could also just be turned into a static method where the "parent" argument is required.
/// <summary>Setting a toolTip on a custom control unfortunately doesn't set it on child
/// controls within its drawing area. This is a workaround for that.</summary>
private void PropagateToolTips(Control parent = null)
{
parent = parent ?? this;
string toolTip = toolTip1.GetToolTip(parent);
if (toolTip == "")
toolTip = null;
foreach (Control child in parent.Controls)
{
// If the parent has a toolTip, and the child control does not
// have its own toolTip set - set it to match the parent toolTip.
if (toolTip != null && String.IsNullOrEmpty(toolTip1.GetToolTip(child)))
toolTip1.SetToolTip(child, toolTip);
// Recurse on the child control
PropagateToolTips(child);
}
}
Note that the behaviour is undefined if you're using more than one ToolTip instance to manage parent and child control toolTips.
I'm programming in WPF(C#). I have a lot of controls in my Window. I normal situation, pressing TAB button causes to move focus from starting point(1) to next control (2) and then (3) and ... At the end of this scenario, I need to move focus from end point(17) to start point(1) as you see below:
How can I do it?
I need some thing like this method:
MoveFocus(Control controlName)
{
// code...
}
I am developing a Kinect game in C# where the user needs to click 2 buttons at the same time by hovering over one button with each hand.
However, with my current code, when the user hovers with one hand over a button, the other buttons get disabled and the other hand can only click when the first hand stops hovering over a button.
To solve this, I'm thinking of queuing the second click while the first click is being processed. To do this, I have used the following code based on this link
private Queue<System.Windows.Controls.Button> Button_Queue = new Queue<System.Windows.Controls.Button>();
private bool isProcessing = false;
private void Button_Click((object sender, RoutedEventArgs e){
if(isProcessing){
Button_Queue.Enqueue(this);
}
else
{
isProcessing = true;
// code here
isProcessing = false;
while(Button_Queue.Count > 0){
Button_Queue.Dequeue().PerformClick();
}
}
However, the Button_Queue.Enqueue(this) line shows the error
"The best overloaded method match for Queue.Enqueue has invalid
arguments."
I'm guessing this is because the button click event cannot be queued in a queue declared with the type Button.
Do you have any suggestions for how to create this queue of button click events or another way to handle multiple clicks from the user?
You don't need to queue the event. If isProcessing is true, then the other button was already clicked, so you can handle the event for both button clicks from that point on.
You could measure the time between the two clicks, to work out if it validates as a "two buttons clicked at the same time" event.
Have you considered a more low-level approach? The first thing that came to mind was to create two hot areas instead of buttons and monitor whether the user's hands are inside those areas at the same time.
It is unclear to me why another button is disabled when you hand is hovering over another object. Without seeing the code, I would say that you are doing something that would cause that -- and there is no reason to.
Additionally, you should be using interaction concepts centered around a gesture system and not something that is written for a mouse/keyboard input. Using regular UI objects and interacting with them in ways that parallel traditional inputs will only serve to confuse the users.
Have a look at the following two examples, which use a "hover-to-click" and a "press-to-click" interaction
Basic Interaction, for SDK 1.6
Control Basics, for SDK 1.7 (in Kinect for Windows Developer Toolkit)
In both cases, you are using a hit test on custom controls to handle events. Here is an example of a hit test function I use in one of my apps:
private void HitTestHand(HandPosition hand)
{
// quick fix to null pointer exception on exit.
if (Application.Current.MainWindow == null)
return;
Point pt = new Point(hand.X, hand.Y);
IInputElement input = Application.Current.MainWindow.InputHitTest(pt);
if (hand.CurrentElement != input)
{
var inputObject = input as DependencyObject;
var currentObject = hand.CurrentElement as DependencyObject;
// If the new input is a child of the current element then don't fire the leave event.
// It will be fired later when the current input moves to the parent of the current element.
if (hand.CurrentElement != null && Utility.IsElementChild(currentObject, inputObject) == false)
{
// Raise the HandLeaveEvent on the CurrentElement, which at this point is the previous element the hand was over.
hand.CurrentElement.RaiseEvent(new HandInputEventArgs(HoverDwellButton.HandLeaveEvent, hand.CurrentElement, hand));
}
// If the current element is the parent of the new input element then don't
// raise the entered event as it has already been fired.
if (input != null && Utility.IsElementChild(inputObject, currentObject) == false)
{
input.RaiseEvent(new HandInputEventArgs(HoverDwellButton.HandEnterEvent, input, hand));
}
hand.CurrentElement = input;
}
else if (hand.CurrentElement != null)
{
hand.CurrentElement.RaiseEvent(new HandInputEventArgs(HoverDwellButton.HandMoveEvent, hand.CurrentElement, hand));
}
}
Notice that an event is being fired on the element below the hand cursor. Examples of these elements can be found in the two links above (the HoverDwellButton is what I use with the above code sample).
Two events on two different elements, or the same element, can fire at any time with this. You can easily keep track of which user is over which button, if that button is in the process of being pressed, or if it has been pressed.
The key to all this is not using a UI paradigm that isn't designed for gesture systems! Don't try to shoehorn the keyboard/mouse event structure into a gesture based system -- it will only cause you more pain in the long run and cause your users confusion.