Как локализовать элемент управления WPF 4.0 DatePicker - PullRequest
11 голосов
/ 09 сентября 2010

Когда вы снимаете флажок в новом элементе управления WPF 4.0 DatePicker, отображается «Выберите дату»

alt text

Есть ли способ локализовать текст?

Ответы [ 4 ]

24 голосов
/ 04 мая 2011

Я взял идею Мэтта и несколько расширил ее;Я реализовал Attached Behavior, который позволяет вам определять водяной знак для каждого элемента управления DatePicker через XAML.Вот код:

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;
        }
    }
}

Вот пример 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>
10 голосов
/ 04 февраля 2011

Вот как это сделать без получения нового элемента управления из DatePicker:

Настройка водяного знака WPF DatePicker

4 голосов
/ 24 сентября 2010

К сожалению, установить текст водяного знака немного сложно.

Как это можно сделать, вы можете увидеть в этой статье: Изменение текста водяного знака в элементе управления DatePicker

1 голос
/ 04 июня 2015

Уэйн, это прекрасно работает, но не работает, когда DatePicker является частью DataGridColumnHeader и иногда, когда DatePicker находится на элементе управления, который сначала скрыт, а затем видим.Решение Мэтта Хэмилтона работает только на onLoad, и когда вы меняете selectedDate, снова появляется раздражающий выбор водяного знака даты.Самое простое решение - просто переопределить событие OnRender в пользовательском классе.Если вы установили свойство водяного знака, а не содержимое водяного знака, вам также необходимо переопределить событие onload.Полный класс здесь:

public class myDateTimePicker : DatePicker
{

    public string Watermark { get; set; }

    protected override void OnSelectedDateChanged(SelectionChangedEventArgs e)
    {
        base.OnSelectedDateChanged(e);
        //SetWatermark();
    }

    protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);
        SetWatermark();
    }

    private void SetWatermark()
    {
        FieldInfo fiTextBox = typeof(DatePicker).GetField("_textBox", BindingFlags.Instance | BindingFlags.NonPublic);
        if (fiTextBox != null)
        {
            DatePickerTextBox dateTextBox = (DatePickerTextBox)fiTextBox.GetValue(this);
            if (dateTextBox != null)
            {
                if (string.IsNullOrWhiteSpace(this.Watermark))
                {
                    this.Watermark = "Custom watermark";
                }

                // if you set property this way then you need to override OnSelectedDateChanged event
                //PropertyInfo piWatermark = typeof(DatePickerTextBox).GetProperty("Watermark", BindingFlags.Instance | BindingFlags.NonPublic);
                //if (piWatermark != null)
                //{
                //    piWatermark.SetValue(dateTextBox, this.Watermark, null);
                //}

                var partWatermark = dateTextBox.Template.FindName("PART_Watermark", dateTextBox) as ContentControl;
                if (partWatermark != null)
                {
                    partWatermark.Foreground = new SolidColorBrush(Colors.Gray);
                    partWatermark.Content = this.Watermark;
                }
            }
        }
    }

}
...