Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to localize the WPF 4.0 DatePicker control

When you clear the box on the new WPF 4.0 DatePicker control it shows "Select a date"

alt text

Is there a way to localize the text?

like image 322
Eduardo Molteni Avatar asked Sep 08 '10 22:09

Eduardo Molteni


2 Answers

I have taken Matt's idea, and extended it somewhat; I've implemented an Attached Behaviour which allows you to define the watermark for each DatePicker control through XAML. Here is the code:

namespace DatePickerWatermark
{
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Controls.Primitives;
    using System.Windows.Media;

    public static class DatePickerWatermarkBehaviour
    {
        public static readonly DependencyProperty WatermarkProperty =
            DependencyProperty.RegisterAttached(
                "Watermark",
                typeof(string),
                typeof(DatePickerWatermarkBehaviour),
                new UIPropertyMetadata(null, OnWatermarkChanged));

        public static string GetWatermark(Control control)
        {
            return (string)control.GetValue(WatermarkProperty);
        }

        public static void SetWatermark(Control control, string value)
        {
            control.SetValue(WatermarkProperty, value);
        }

        private static void OnWatermarkChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            var datePicker = dependencyObject as DatePicker;
            if (datePicker == null)
                return;

            if ((e.NewValue != null) && (e.OldValue == null))
                datePicker.Loaded += DatePickerLoaded;
            else if ((e.NewValue == null) && (e.OldValue != null))
                datePicker.Loaded -= DatePickerLoaded;
        }

        private static void DatePickerLoaded(object sender, RoutedEventArgs e)
        {
            var datePicker = sender as DatePicker;
            if (datePicker == null)
                return;

            var datePickerTextBox = GetFirstChildOfType<DatePickerTextBox>(datePicker);
            if (datePickerTextBox == null)
                return;

            var partWatermark = datePickerTextBox.Template.FindName("PART_Watermark", datePickerTextBox) as ContentControl;
            if (partWatermark == null)
                return;

            partWatermark.Content = GetWatermark(datePicker);
        }

        private static T GetFirstChildOfType<T>(DependencyObject dependencyObject) where T : DependencyObject
        {
            if (dependencyObject == null)
                return null;

            for (var i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
            {
                var child = VisualTreeHelper.GetChild(dependencyObject, i);
                var result = (child as T) ?? GetFirstChildOfType<T>(child);
                if (result != null)
                    return result;
            }

            return null;
        }
    }
}

Here's some example XAML:

<Window x:Class="DatePickerWatermark.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:b="clr-namespace:DatePickerWatermark" Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
            <Style TargetType="DatePicker">
                <Setter Property="Margin" Value="10,5"/>
            </Style>
            <Style x:Key="EnglishDatePicker" TargetType="DatePicker" BasedOn="{StaticResource {x:Type DatePicker}}">
                <Setter Property="b:DatePickerWatermarkBehaviour.Watermark" Value="Please select a date:"/>
            </Style>
        </Grid.Resources>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <DatePicker Grid.Row="0" b:DatePickerWatermarkBehaviour.Watermark=""/>
        <DatePicker Grid.Row="1" b:DatePickerWatermarkBehaviour.Watermark="Wählen Sie ein Datum"/>
        <DatePicker Grid.Row="2" b:DatePickerWatermarkBehaviour.Watermark="Sélectionner une date"/>
        <DatePicker Grid.Row="3" Style="{StaticResource EnglishDatePicker}"/>
        <DatePicker Grid.Row="4" Style="{StaticResource EnglishDatePicker}"/>
    </Grid>
</Window>
like image 114
Wayne Maurer Avatar answered Nov 02 '22 03:11

Wayne Maurer


Here's how to do it without having to derive a new control from DatePicker:

Customizing the WPF DatePicker's Watermark

like image 10
Matt Hamilton Avatar answered Nov 02 '22 04:11

Matt Hamilton