【问题标题】:WPF DatePicker Watermark uses wrong Language, but the Dateformat is correctWPF DatePicker Watermark 使用错误的语言,但日期格式正确
【发布时间】: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();
    }
}

【问题讨论】:

    标签: c# wpf internationalization datepicker


    【解决方案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;
                    }
                }
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2015-07-06
      • 2014-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多