Водяной знак WPF DatePicker использует неправильный язык, но Dateformat является правильным

у меня очень странная проблема:

на моей машине DatePicker изменяет свой водяной знак и формат даты в соответствии с языком/культурой, которые я хочу установить.

Если я скопирую свое приложение на другие компьютеры, произойдет следующее:

на каком-то компьютере он работает так же, как на моей машине. На других компьютерах изменяется только формат даты, но не водяной знак! Излишне говорить, что очень некрасиво иметь datepicker с, например, немецкой датой, но английской водяной знак.

в чем причина такого поведения?

для i18n я использую следующий код:

App.код XAML.cs:

public partial class App : Application
{
    public App()
    {
        CultureInfo ci = new CultureInfo("de-DE"); 
        Thread.CurrentThread.CurrentCulture = ci;
        Thread.CurrentThread.CurrentUICulture = ci;
    }
}

WindowMain.код XAML.cs:

public partial class WindowMain : RibbonWindow
{
    public WindowMain()
    {
        this.Language = XmlLanguage.GetLanguage("de-DE");
        this.InitializeComponent();
    }
}

3 ответов


одно могу сказать,Watermark на DatePicker реализована багги, нет легкого доступа. Возможно, из-за этой сложности локализация текста не работает. Есть замечательная статья @Matt Hamilton, цитата из здесь:

что-то, что многим людям (включая меня) не нравится в DatePicker, хотя, по умолчанию, если дата не отображается, он показывает текст "выберите дату" в качестве водяного знака, и этот текст запечен в контроль-он не локализован и не доступен ни для одного публичного объекта. Это особенно расстраивает, если рассматриваемая дата является необязательной, и вы не обязательно хотите предлагать пользователям выбрать ее.

в той же статье он предоставляет решение о том, как получить доступ к Watermark. Здесь:

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

@Wayne Maurer создано универсальное решение в виде прикрепленный свойства зависимостей:

<DatePicker Grid.Row="2" 
            local:DatePickerWatermarkBehaviour.Watermark="Select the date" />

вы должны быть основаны на текущей культуре, установить текст для водяных знаков, например, используя пример выше.

Note: в Silverlight до Watermark на DatePicker доступ [link]:

DatePickerTextBox box = base.GetTemplateChild("TextBox") as DatePickerTextBox;
box.Watermark = "Type or select a date --> "; 

на самом деле очень легко установить текст с водяными знаками:

<DatePicker>
  <DatePicker.Resources>
    <Style TargetType="DatePickerTextBox">
      <Setter Property="Text" Value="Watermark Text"/>
    </Style>
  </DatePicker.Resources>
</DatePicker>

http://www.admindiaries.com/change-datepicker-watermark-in-wpf/


решение Wayne отлично работает, но не работает, когда 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;
                }
            }
        }
    }

}