Archive for February, 2011

WPF: Focus DatePicker on Text in TextBox

February 20th, 2011

I’ve been using the DatePicker control (which can be found in WPF 4.0 as well as the WPF Toolkit) and have come across a situation where I would like to set keyboard focus on a DatePicker programmatically so that the user can immediately begin typing a date into the control. Well like many other people out there I attempted to do this by calling the controls Focus() method and when that didn’t have the desired results I tried Keyboard.Focus() and passed it the DatePicker. This also didn’t accomplish what I was looking for.

In the above cases the DatePicker would indeed gain focus, however you could not immediately begin typing in a date. If you pressed a navigational key on the keyboard such as Tab or any of the directional arrows it would then put the keyboard focus into the TextBox portion of the control and highlight any existing text.

DatePicker without focus on text

Focus, but not on text...



DatePicker with focus on text

Focus on text!


Since this is exactly the end result I was after I set about automating this in code and arrived at the following solution. Basically all I’m doing is simulating the Up Arrow being pressed on the DatePicker control, this causes the control to move focus to the internal TextBox. It’s very hacky but it’s the best thing I could come up with without inheriting from DatePicker which I’d like to avoid. I wrapped the code up in a nice extension method for ease of use, and that’s what you see below.

using System.Windows.Controls;
using System.Windows.Input;
 
namespace CGS
{
    public static class DatePickerExtensions
    {
        public static void FocusOnText(this DatePicker datePicker)
        {
            Keyboard.Focus(datePicker);
 
            var eventArgs = new KeyEventArgs(Keyboard.PrimaryDevice,
                                             Keyboard.PrimaryDevice.ActiveSource,
                                             0,
                                             Key.Up);
            eventArgs.RoutedEvent = DatePicker.KeyDownEvent;
 
            datePicker.RaiseEvent(eventArgs);
        }
    }
}

If anyone knows of a cleaner, more legitimate way to accomplish this please let me know! As always questions and comments are welcome and appreciated.