WPF toolkit DatePicker изменит значение по умолчанию 'show calendar'

Я использую последний набор инструментов WPF, в частности DatePicker. Все работает нормально, но когда значения не задано, в окне DatePickerTextBox появляется текст "SHOW CALENDAR" по умолчанию. Я хочу иметь возможность изменить это значение в WPF.

Один сказал мне загрузить исходный код, добавить новое свойство Dependency и перекомпилировать dll. Это круто, но что, если новая версия будет выпущена?

Вот почему я хотел бы настроить этот элемент таким образом, чтобы я мог переопределить эту строку по умолчанию. Любая идея, как это сделать?

Спасибо!

Ответ 1

OK. Я нашел решение самостоятельно.

<Style TargetType="{x:Type toolkit:DatePickerTextBox}">
    <Setter Property="Text" Value="Bitte wählen" />
</Style>

В любом случае вы должны знать о факте, что есть DependencyProperty под названием Watermark, который должен быть установлен вместо Text.

Проблема в том, что с последней версией MS (около июня 2009 года) они сделали это свойство readonly по неизвестной причине. Это означает, что это единственный взлом, который я составил, хотя возникает исключение в первый раз, потому что DatePicker пытается проанализировать строку (он предполагает, что текст будет Date), но обычно вы его не заметите.

Другая возможность - напрямую отредактировать исходный код от MS и переопределить метод SetWaterMark() + добавить собственное свойство Dependency (MyWaterMark или что-то еще). Но тогда вы не можете использовать предоставленный dll. Они сказали, что он будет исправлен с .NET 4 realese, посмотрим.

Ответ 2

    void _datePicker1_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
    {
        if (_datePicker1.SelectedDate != null) return;

        FieldInfo fiTextBox = typeof(DatePicker)
            .GetField("_textBox", BindingFlags.Instance | BindingFlags.NonPublic);

        if (fiTextBox != null)
        {
            DatePickerTextBox dateTextBox =
              (DatePickerTextBox)fiTextBox.GetValue(_datePicker1);

            if (dateTextBox != null)
            {
                PropertyInfo piWatermark = dateTextBox.GetType()
                  .GetProperty("Watermark", BindingFlags.Instance | BindingFlags.NonPublic);

                if (piWatermark != null)
                {
                    piWatermark.SetValue(dateTextBox, "", null);
                }
            }
        }
    }

вам нужно подключить событие Load также с тем же кодом.

Ответ 3

это отлично работает, но вам придется переопределить метод onrender в пользовательском классе. В этом методе, если вы задаете содержание водяных знаков, а не свойство, нет необходимости переопределять событие OnSelectedDateChanged. Полный код находится здесь:

    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 select a date";
                }

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

Ответ 4

Вы также можете сделать это:

Добавьте текстовое поле и датупик в форму со следующими настройками:

В вашем окне .xaml:

<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="22" Margin="38,38,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
    <DatePicker x:Name="datePicker" HorizontalAlignment="Left" Margin="130,37,0,0" VerticalAlignment="Top" Width="28" BorderBrush="Transparent" SelectedDateChanged="datePicker_SelectedDateChanged"/>

И в вашем window.xaml.cs:

private void datePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
    {
        textBox.Text = datePicker.SelectedDate.Value.ToString("dd.MM.yyyy");
    }

Результат выглядит следующим образом: klick