Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Last Resort WPF Focus Solution

0.00/5 (No votes)
26 Aug 2015 1  
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:

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here