Localizing a Silverlight DatePicker control, a study in pain thresholds

For shame Microsoft. There is currently no way to localize a DatePicker. Instead of letting us simply specify a format string or any of the other beautiful conventions we are forced to basically re-template the entire control.

In our application, at my day job, we support many different languages/cultures. This was becoming a mess with the various date formats so we decreed that all dates would be in the ISO standard format (yyyy-MM-dd HH:mm:ss). Styling everything in the app was a 10 minute job, until I got to the DatePickers that we use for our search fields. I couldn’t find a nice FormatString to set in XAML. I couldn’t find a way to set anything else in the code behind either. I changed how we display the selected date by reformatting the text string that the Text property is bound to. That was fixed, but now I was left with a watermark stating when the actual format was yyyy-mm-dd I resorted to Google.

I found a lot of rants and only a couple possible solutions.

http://blogs.msdn.com/b/silverlight_sdk/archive/2010/05/06/changing-the-watermark-text-in-a-datepicker-control.aspx

This blog shows a way to change the watermark, but the solution quickly fails after selecting a date and then deleting it. It will revert back to the original watermark. Unacceptable.

One of the last comments says that this code will fix it:

public class CustomDatePicker : DatePicker { public CustomDatePicker() { SelectedDateChanged += DateChanged; Unloaded += CustomDatePickerUnloaded; }

public override void OnApplyTemplate() { base.OnApplyTemplate(); HandleWatermark(); }

private void DateChanged(object sender, SelectionChangedEventArgs e) { HandleWatermark(); }

private void CustomDatePickerUnloaded(object sender, RoutedEventArgs e) { SelectedDateChanged -= DateChanged; }

public void HandleWatermark() { var box = GetTemplateChild(“TextBox”) as DatePickerTextBox;

   if (box == null) return;

   if (SelectedDateFormat == DatePickerFormat.Short)
       box.Watermark = "mm/dd/yyyy";

} }

This code is closer, but there is still a bug. From the time that you delete the date until the time that you unfocus the DatePicker the original watermark is displayed. So close, but so far.

I eventually found this solution, which seems like entirely too much work for such a simple problem. You basically have to style the DatePicker and the DatePickerTextBox that it contains.

You then reference this style in your DatePicker control as follows:

And there you go, a several hundred line solution to a one line problem. For shame Microsoft.