我目前正在使用 WPF 日历控件。日期名称显示为 Su、Mo、Tu 等。但我希望这些名称显示为 Sun、Mon、Tue 等。我发现没有数据模板属性可以实现这一点。
任何建议将不胜感激。
谢谢
我目前正在使用 WPF 日历控件。日期名称显示为 Su、Mo、Tu 等。但我希望这些名称显示为 Sun、Mon、Tue 等。我发现没有数据模板属性可以实现这一点。
任何建议将不胜感激。
谢谢
最后,我用下面的转换器解决了它,
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();
}
}
我已经调查过了,不幸的是,我认为你无法实现你想要的。
首先,我发现在 MSDN的自定义日期和时间格式字符串StringFormat
页面中显示三个字符的日期名称:
StringFormat=ddd
然后我认为您可能会在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 寻找控件的默认值ControlTemplate
进行Calendar
进一步实验。如果你看一下ControlTemplate
,你会看到一个Style
名为CalendarItemStyle
.
在 that Style
is aControlTemplate
和它的Resources
部分,你会看到 aDataTemplate
和 key {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
的 s):
现在,如果您查看Binding
其中的TextBlock
,您会看到不幸的是,它设置为{Binding}
。这意味着它使用整个数据绑定值,而不是StringFormat
在DateTime
对象上设置特定值。这意味着我们不能使用 a StringFormat
,因为数据绑定值已经是 a string
。
我也调查过。
我见过的唯一解决方案是使用自定义本地化字典本地化日历,但不幸的是没有给出我们可以使用的键。
反编译我发现的日历控件,日历控件使用本机函数(nativeGetCalendarData())来本地化日历,所以我将无法轻松检索这些键:(
请参阅此站点nullskull.com。可下载源包含日期名称转换器和描述
在这里聚会迟到了,但我想出了一个稍微不同的解决方案,希望它能在国际上更可靠地工作。这是一个两部分的事情。首先,为上面@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 逻辑设置,应该是可靠的。我们必须使用 anIMultiValueConverter
因为我们也依赖于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;
}