如何本地化WPF 4.0日期选择器控件
清除新WPF 4.0 DatePicker控件上的框时,它将显示“选择日期”如何本地化WPF 4.0日期选择器控件,wpf,localization,wpf-controls,datepicker,Wpf,Localization,Wpf Controls,Datepicker,清除新WPF 4.0 DatePicker控件上的框时,它将显示“选择日期” 有没有办法本地化文本?不幸的是,设置水印文本有点棘手 如何做到这一点您可以在本文中看到:以下是如何做到这一点,而不必从DatePicker派生新控件: 我采纳了马特的想法,并对其进行了一些扩展;我已经实现了一个附加行为,它允许您通过XAML为每个DatePicker控件定义水印。代码如下: namespace DatePickerWatermark { using System.Windows; us
有没有办法本地化文本?不幸的是,设置水印文本有点棘手
如何做到这一点您可以在本文中看到:以下是如何做到这一点,而不必从DatePicker派生新控件:
我采纳了马特的想法,并对其进行了一些扩展;我已经实现了一个附加行为,它允许您通过XAML为每个DatePicker控件定义水印。代码如下:
namespace DatePickerWatermark
{
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
public static class DatePickerWatermarkBehaviour
{
public static readonly DependencyProperty WatermarkProperty =
DependencyProperty.RegisterAttached(
"Watermark",
typeof(string),
typeof(DatePickerWatermarkBehaviour),
new UIPropertyMetadata(null, OnWatermarkChanged));
public static string GetWatermark(Control control)
{
return (string)control.GetValue(WatermarkProperty);
}
public static void SetWatermark(Control control, string value)
{
control.SetValue(WatermarkProperty, value);
}
private static void OnWatermarkChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var datePicker = dependencyObject as DatePicker;
if (datePicker == null)
return;
if ((e.NewValue != null) && (e.OldValue == null))
datePicker.Loaded += DatePickerLoaded;
else if ((e.NewValue == null) && (e.OldValue != null))
datePicker.Loaded -= DatePickerLoaded;
}
private static void DatePickerLoaded(object sender, RoutedEventArgs e)
{
var datePicker = sender as DatePicker;
if (datePicker == null)
return;
var datePickerTextBox = GetFirstChildOfType<DatePickerTextBox>(datePicker);
if (datePickerTextBox == null)
return;
var partWatermark = datePickerTextBox.Template.FindName("PART_Watermark", datePickerTextBox) as ContentControl;
if (partWatermark == null)
return;
partWatermark.Content = GetWatermark(datePicker);
}
private static T GetFirstChildOfType<T>(DependencyObject dependencyObject) where T : DependencyObject
{
if (dependencyObject == null)
return null;
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
{
var child = VisualTreeHelper.GetChild(dependencyObject, i);
var result = (child as T) ?? GetFirstChildOfType<T>(child);
if (result != null)
return result;
}
return null;
}
}
}
namespace DatePickerWatermark
{
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Controls.Primitives;
使用System.Windows.Media;
公共静态类DatePickerWaterMarkBehavior
{
公共静态只读从属属性WatermarkProperty=
DependencyProperty.RegisterAttached(
“水印”,
类型(字符串),
类型(DatePickerWaterMarkBehavior),
新的UIPropertyMetadata(null,OnWatermarkChanged));
公共静态字符串GetWatermark(控件)
{
返回(字符串)控件.GetValue(WatermarkProperty);
}
公共静态无效设置水印(控件,字符串值)
{
control.SetValue(WatermarkProperty,value);
}
WatermarkChanged上的私有静态无效(DependencyObject DependencyObject,DependencyPropertyChangedEventArgs e)
{
var datePicker=作为日期选择器的dependencyObject;
if(datePicker==null)
返回;
如果((e.NewValue!=null)&&(e.OldValue==null))
datePicker.Loaded+=DatePickerLoaded;
else如果((e.NewValue==null)和&(e.OldValue!=null))
datePicker.Loaded-=DatePickerLoaded;
}
私有静态void DatePickerLoaded(对象发送方,RoutedEventArgs e)
{
var datePicker=发送方作为日期选择器;
if(datePicker==null)
返回;
var datePickerTextBox=GetFirstChildOfType(datePicker);
如果(datePickerTextBox==null)
返回;
var partWatermark=datePickerTextBox.Template.FindName(“PART\u水印”,datePickerTextBox)作为ContentControl;
如果(partWatermark==null)
返回;
partWatermark.Content=GetWatermark(日期选择器);
}
私有静态T GetFirstChildOfType(DependencyObject DependencyObject),其中T:DependencyObject
{
if(dependencyObject==null)
返回null;
对于(var i=0;i
下面是一些XAML示例:
<Window x:Class="DatePickerWatermark.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:b="clr-namespace:DatePickerWatermark" Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<Style TargetType="DatePicker">
<Setter Property="Margin" Value="10,5"/>
</Style>
<Style x:Key="EnglishDatePicker" TargetType="DatePicker" BasedOn="{StaticResource {x:Type DatePicker}}">
<Setter Property="b:DatePickerWatermarkBehaviour.Watermark" Value="Please select a date:"/>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DatePicker Grid.Row="0" b:DatePickerWatermarkBehaviour.Watermark=""/>
<DatePicker Grid.Row="1" b:DatePickerWatermarkBehaviour.Watermark="Wählen Sie ein Datum"/>
<DatePicker Grid.Row="2" b:DatePickerWatermarkBehaviour.Watermark="Sélectionner une date"/>
<DatePicker Grid.Row="3" Style="{StaticResource EnglishDatePicker}"/>
<DatePicker Grid.Row="4" Style="{StaticResource EnglishDatePicker}"/>
</Grid>
</Window>
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;
}
}
}
}
}
WPF方面有什么解决方案吗?