我目前正在使用WPF日历控件。日名称显示为Su,Mo,Tu等。但我希望这些名称显示为Sun,Mon,Tue等。我发现没有数据模板属性来实现这个。
任何建议都将不胜感激。
由于
答案 0 :(得分:1)
我已经调查了这一点,不幸的是,我认为你无法达到你想要的效果。
首先,我发现StringFormat
在MSDN的Custom Date and Time Format Strings页面显示三个字符日名称:
StringFormat=ddd
然后我认为您可以在Custom date format for WPF Calendar CalendarItems帖子中找到解决其余问题的方法。因此,调整@Quartermeister的想法,我可以尝试以下方法:
<Calendar>
<Calendar.CalendarButtonStyle>
<Style TargetType="primitives:CalendarButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="primitives:CalendarButton">
<primitives:CalendarButton>
<TextBlock Text="{Binding Day, StringFormat=ddd}"/>
</primitives:CalendarButton>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Calendar.CalendarButtonStyle>
</Calendar>
你可以想象,我离开了,因为这回答了另一个问题。所以我回到MSDN找the default ControlTemplate
for the Calendar
control进一步试验。如果您查看ControlTemplate
,则会看到名为Style
的{{1}}。
由于CalendarItemStyle
是Style
并且在ControlTemplate
部分,您会看到Resources
,其中包含密钥DataTemplate
。最后,在{x:Static CalendarItem.DayTitleTemplateResourceKey}
中,您会看到负责显示日期名称的DataTemplate
:
TextBlock
我增加了日期名称的大小,因此我们可以确定这是正确的<TextBlock Foreground="#FF333333"
FontWeight="Bold"
FontSize="9.5"
FontFamily="Verdana"
Margin="0,6,0,6"
Text="{Binding}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
。 (忽略顶部奇怪的TextBlock
- 他们就是这样,因为我没有复制他们的Button
s:
现在,如果您查看ControlTemplate
中的Binding
,您会看到不幸的是,它被设置为TextBlock
。这意味着它使用整个数据绑定值,而不是在{Binding}
对象上设置特定的StringFormat
。这意味着我们无法使用DateTime
,因为数据绑定值已经是StringFormat
。
答案 1 :(得分:1)
最后,我用以下转换器解决了它,
public class CalendarDayNameConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var daynames = CultureInfo.CurrentCulture.DateTimeFormat.DayNames;
string dayname = value.ToString();
return daynames.First(t => t.StartsWith(dayname)).Substring(0, 3);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
答案 2 :(得分:0)
我也一直在研究它。
我见过的唯一解决方案是使用自定义本地化字典本地化日历,但遗憾的是没有给出密钥,我们可以使用。
重新编译我发现的日历控件,日历控件使用本机函数(nativeGetCalendarData())来本地化日历,因此我无法以简单的方式检索这些键:(
答案 3 :(得分:0)
请参阅此网站nullskull.com。可下载源包含日期名称转换器和说明
答案 4 :(得分:0)
在这里晚了聚会,但是我想出了一个稍微不同的解决方案,希望它将在国际上更加可靠地工作。这是两部分的事情。首先,按照上面@Sheridan所述,为日期名称制作一个模板:
<DataTemplate x:Key="{x:Static CalendarItem.DayTitleTemplateResourceKey}">
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource CalendarDayNameConverter}">
<Binding Path="(Grid.Column)" RelativeSource="{RelativeSource Self}" Mode="OneWay"/>
<Binding Path="FirstDayOfWeek" RelativeSource="{RelativeSource AncestorType={x:Type Calendar}}" Mode="OneWay"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
当然,请根据您的要求进行格式化。这里的技巧是将Text
绑定到Grid.Column
而不是通常的数据上下文值(WPF提供的两个字母的天名称)。网格列号由内部WPF logic设置,应该可靠。我们必须使用IMultiValueConverter
,因为我们也依赖于父FirstDayOfWeek
控件的Calendar
值:
public sealed class CalendarDayNameConverter : IMultiValueConverter
{
/// <inheritdoc/>
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values?.Length > 0 && values[0] is int index)
{
var dayNames = culture?.DateTimeFormat?.AbbreviatedDayNames;
if (dayNames?.Length > 0)
{
var firstDayOfWeek = values.Length > 1 && values[1] is DayOfWeek d ? d : culture.DateTimeFormat.FirstDayOfWeek;
return dayNames[(index + (int)firstDayOfWeek) % dayNames.Length];
}
}
return DependencyProperty.UnsetValue;
}
/// <inheritdoc/>
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) =>
null;
}