WPF DatePicker Watermark 使用错误的语言,但日期格式正确

Posted

技术标签:

【中文标题】WPF DatePicker Watermark 使用错误的语言,但日期格式正确【英文标题】:WPF DatePicker Watermark uses wrong Language, but the Dateformat is correct 【发布时间】:2013-09-06 12:28:16 【问题描述】:

我有一个很奇怪的问题:

在我的机器上,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();
    

【问题讨论】:

【参考方案1】:

设置水印文字其实很简单:

<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】:

我可以说一件事,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 中对 WatermarkDatePicker 进行访问 [link]:

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

【讨论】:

感谢您的回答!它的信息量很大,但是它没有解释为什么本地化实际上可以在某些机器上运行。这让我很困惑。 @MC:是的,我同意这很奇怪。在有操作系统的机器上?它们是相同的操作系统还是不同的操作系统? 2台机器有WinXP 2台机器Win7。 1 win xp 和 1 win7 机器工作。其他人没有。所以它不是操作系统。但是两台工作机器都安装了 Visual Studio。我的得到了 VS2012 pro 另一个 VS2010 express。是否有可能我忘记将一些程序集复制到用户计算机,因为它适用于开发人员机器?如果是:哪些? @MC:我认为正确地说是DatePicker的开发人员。我怀疑在不同操作系统的情况下。对于通用解决方案,我建议通过附加的依赖属性在Watermark 中设置文本,或者大多数以制作DatePicker 控件,因为它是Button(打开Calendar)和TextBox 嗯,谢谢你的帮助。如果我(曾经)发现是什么让日期选择器本地化在特定计算机上工作/失败,我会在这里发布。【参考方案3】:

Wayne 解决方案效果很好,但当 DatePicker 是 DataGridColumnHeader 的一部分时不起作用,有时当 DatePicker 处于先隐藏然后可见的控件上时不起作用。 Matt Hamilton 的解决方案仅适用于 onLoad,当您更改 selectedDate 时,再次出现烦人的 Select a date watermark。最简单的解决方案就是在自定义类中覆盖 OnRender 事件。如果您设置 watermark 属性而不是您需要覆盖 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;
                
            
        
    


【讨论】:

以上是关于WPF DatePicker Watermark 使用错误的语言,但日期格式正确的主要内容,如果未能解决你的问题,请参考以下文章

Wpf DatePicker 水印修改为中文

WPF + DatePicker + UpdateSourceTrigger = 显式

在 WPF 的 DatePicker 中显示当前日期

WPF:DatePicker 文本垂直居中

WPF 4.0 DatePicker 快速录入

编辑 WPF 工具包以仅获取 DatePicker