WPF DatePicker Watermark使用错误的语言,但Dateformat是正确的

时间:2013-09-03 10:03:08

标签: c# wpf internationalization 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 个答案:

答案 0 :(得分:5)

有一件事我可以说WatermarkDatePicker实施了错误,没有简单的访问权限。也许,由于这种困难,文本的本地化不起作用。有一篇精彩的文章@Matt Hamilton,引自here

  

很多人(我自己也不喜欢)关于DatePicker的东西,默认情况下,如果没有显示日期,它会显示文本“选择日期”作为水印,并且此文本被烘焙进入控制 - 它没有本地化或任何公共财产可访问。如果相关日期是可选的,并且您不一定要提示用户选择一个日期,那么这尤其令人沮丧。

在同一篇文章中,他提供了如何访问Watermark的决定。这里:

How to localize the WPF 4.0 DatePicker control

@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 --> "; 

答案 1 :(得分:5)

设置水印文本实际上非常简单:

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

答案 2 :(得分:2)

Wayne解决方案效果很好但是当DatePicker是DataGridColumnHeader的一部分时有效,并且有时当DatePicker处于首先隐藏然后可见的控件上时。 Matt Hamilton的解决方案仅适用于负载,当您更改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;
                }
            }
        }
    }

}