Подтвердить что ты не робот

Как локализовать элемент управления DatePicker WPF 4.0

Когда вы очищаете окно нового элемента управления DatePicker WPF 4.0, он показывает "Выбрать дату"

alt text

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

4b9b3361

Ответ 2

Я принял идею Мэтта и несколько расширил ее; Я реализовал приложение 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>

Ответ 4

Уэйн, это отлично работает, но не работает, когда DatePicker является частью DataGridColumnHeader, а иногда, когда DatePicker находится под контролем, который сначала скрыт, а затем виден. Решение Matt Hamilton работает только 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;
                }
            }
        }
    }

}