0

我目前正在使用 WPF 日历控件。日期名称显示为 Su、Mo、Tu 等。但我希望这些名称显示为 Sun、Mon、Tue 等。我发现没有数据模板属性可以实现这一点。

任何建议将不胜感激。

谢谢

4

5 回答 5

2

最后,我用下面的转换器解决了它,

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();
    }
}
于 2013-10-15T10:40:06.783 回答
1

我已经调查过了,不幸的是,我认为你无法实现你想要的。

首先,我发现在 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 Styleis 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。(忽略顶部奇怪的Buttons - 他们就是那样,因为我没有复制他们ControlTemplate的 s):

在此处输入图像描述

现在,如果您查看Binding其中的TextBlock,您会看到不幸的是,它设置为{Binding}。这意味着它使用整个数据绑定值,而不是StringFormatDateTime对象上设置特定值。这意味着我们不能使用 a StringFormat,因为数据绑定值已经是 a string

于 2013-10-15T09:50:22.387 回答
0

我也调查过。

我见过的唯一解决方案是使用自定义本地化字典本地化日历,但不幸的是没有给出我们可以使用的键。

反编译我发现的日历控件,日历控件使用本机函数(nativeGetCalendarData())来本地化日历,所以我将无法轻松检索这些键:(

于 2013-10-15T10:24:56.057 回答
0

请参阅此站点nullskull.com。可下载源包含日期名称转换器和描述

于 2014-11-13T19:29:29.120 回答
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 逻辑设置,应该是可靠的。我们必须使用 anIMultiValueConverter因为我们也依赖于FirstDayOfWeekCalendar控件的值:

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;
}
于 2019-04-12T18:16:51.880 回答