WPF Toolkit DateTimePicker customisation of header

In my previous post WPF Toolkit PropertyGrid direct update I’ve written about getting the Property Grid from the WPF toolkit. Now I want to tell you about how I got the DateTimePicker to behave my way.

First of all the DateTimePicker is well documented. It offers a lot of properties, methods and events. Samples and solutions are available. But when I use it, it looks like the image below on the left. The header is to small and makes the text unreadable.

datetimepicker-wrong

Calendar with header too small

datetimepicker-right

Calendar the way I like it

After reading a lot of suggestions online I created a customised version of the control that increases the header. That makes the text readable again. The code below hooks into the OnApplyTemplate event from the control and registers for the loading of the child controls. When (finally) the Calendar is loaded the header is adjusted by using the PART_xxx templates provided by Microsoft.

public class CustomDateTimePicker : Xceed.Wpf.Toolkit.DateTimePicker {
    public override void OnApplyTemplate() {
        // 1. Look for the Popup (that holds the calendar)
        base.OnApplyTemplate();
        var popup = Template.FindName("PART_Popup", this) as Popup;
        popup.Loaded += Popup_Loaded;
    }

    private void Popup_Loaded(object sender, RoutedEventArgs e) {
        // 2. When popup is loaded find the Calendar control/part
        var cal = Template.FindName("PART_Calendar", this) as Calendar;
        cal.Loaded += Cal_Loaded;
    }

    private void Cal_Loaded(object sender, RoutedEventArgs e) {
        // 3. When calendar is loaded alter the header
        var cal = sender as Calendar;
        var calItem = cal.Template.FindName("PART_CalendarItem", cal) as CalendarItem;
        var header = calItem.Template.FindName("PART_HeaderButton", calItem) as Button;
        // 4. Finally ...
        if (header != null) {
            header.Height = 30;
            header.Width = 120;
        }
    }
}

In the Resolve editor method (see previous post) I create a CustomDatePicker, set some properties and bind it to the value. Code collapsed below. Now the DateTimePicker behaves my way.

public class InstantUpdatingDateTimePicker : ITypeEditor {
    public FrameworkElement ResolveEditor(PropertyItem propertyItem) {
        var dateTimePicker = new CustomDateTimePicker {
            BorderThickness = new Thickness(0),
            AllowSpin = false,
            AllowTextInput = false,
            ShowButtonSpinner = false,
            TimePickerShowButtonSpinner = false,
            AutoCloseCalendar = true
        };

        var _binding = new Binding("Value"); //bind to the Value property of the PropertyItem
        _binding.Source = propertyItem;
        _binding.ValidatesOnExceptions = true;
        _binding.ValidatesOnDataErrors = true;
        _binding.Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay;
        _binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

        BindingOperations.SetBinding(dateTimePicker,
            Xceed.Wpf.Toolkit.DateTimePicker.ValueProperty,
            _binding);

        return dateTimePicker;
    }
}

About erictummers

Working in a DevOps team is the best thing that happened to me. I like challenges and sharing the solutions with others. On my blog I’ll mostly post about my work, but expect an occasional home project, productivity tip and tooling review.
This entry was posted in Development and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.