Click here to Skip to main content
15,867,686 members
Articles / Desktop Programming / WPF
Tip/Trick

Last Resort WPF Focus Solution

Rate me:
Please Sign up or sign in to vote.
4.86/5 (6 votes)
26 Aug 2015CPOL2 min read 9.1K   5   2
If you are having issues with getting the WPF Focus() method working, then maybe all you need to do is add a delay on the Initialized event before setting the focus. This solution is a nice demonstration of the features of TPL, and how easy TPL can make doing asynchronous programming in the UI.

Introduction

I had a task to set focus on the first control of a RadTilePane that was very dynamic. By this, I mean that the control was the Content of a ContentControl using a DataTemplate with a DataType that used the DataContext to determine the DataTemplate. I read everything, and must have tried everything but nothing worked. Controls have a Focus() method and there is also the FocusManager. I am sure that the Focus() method uses the FocusManager in some way to give the control focus. Finally, I started using the GotFocus event, the FocusManager. GetFocusedElement() and the Debug.Print method to try to understand what was happening. I tried setting the Focus on the Loaded and Initialized events for the UserControl, but neither worked. To make things even weirder, that was control that was getting focus, but is seemed like it was the last one being created. Finally, I decided to try a delay and that worked.

Using the Code

This is what I ended up putting in the constructor of the UserControl:

C#
Initialized += (sender, args) =>
             {
                    var t = Task.Run(() => Task.Delay(250)).ContinueWith(x =>
                    {
                           _password.Focus();
                    }, TaskScheduler.FromCurrentSynchronizationContext());
             };

and it worked.

Conclusion

Before I found this solution, I had struggled with the focus issue numerous times, especially since it was significant enough to the customer for me to spend so much time on it. I will no longer avoid the WPF after this since I understand that the FocusManager suffers from contention with the creation of the VisualTree. I would have thought that Microsoft would have dealt with any issues of timing that would require any such code to be used by developers, but, again, I am wrong. Maybe this will help you quickly solve your focus problem. I set 250 milliseconds for the delay since this seemed that it was short enough that it should not cause any usability issues. A second I think is too long.

Also want to note how clean and easy the implementation is using TPL, which provides a Task.Run, ContinueWith, and a Task.Delay, along with the TaskScheduler.FromCurrentSynchronizationContext(). It seems that people still rely heavily on the BackgroundWorker, and I cannot understand why.

History

  • 08/25/2015: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Clifford Nelson Consulting
United States United States
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with BioNano Genomics in San Diego, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.

Comments and Discussions

 
Answertry this instead Pin
demicro26-Aug-15 18:59
demicro26-Aug-15 18:59 
I've run into the same issue several times and can usually solve it with this:

control.UpdateLayout();
control.Focus();

Should be able to just throw that into your Loaded handler.
AnswerRe: try this instead Pin
Clifford Nelson27-Aug-15 3:35
Clifford Nelson27-Aug-15 3:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.