Windows 7 上的 WPF:ValueConverter 中的 GetCultureInfo 在 Provide Value 上导致 StaticResourceExtension 异常

WPF on Windows 7: GetCultureInfo in ValueConverter causing StaticResourceExtension exception on Provide Value

如果标题有点混乱,我很抱歉,但我真的不知道如何简短地描述这个问题。 我有一个 wpf windows 应用程序,它在 Windows 8 和 10 中运行良好,但在加载主界面时在 Windows 7 上崩溃。 应用程序重新启动的异常是:

Provide value on 'System.Windows.StaticResourceExtension' threw an exception. StackTrace : at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri) at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri) at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream) at System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc) at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties) at System.Windows.Application.DoStartup() at System.Windows.Application.<.ctor>b__1(Object unused) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

Google 告诉我问题可能是我在 xaml 文件中定义一些静态资源 (Provide value on 'System.Windows.StaticResourceExtension) 的顺序。实际上我在 Window.Resources 标签中有一些 DataTemplate 定义为静态资源,但正如 post 所说,它们是按正确的顺序定义的,Window.Resources 标签是第一个 child 的 Window 标签:

<Window x:Class="FlyMasterSyncGui.Forms.FlightLog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:FlyMasterSyncGui.Forms"
    xmlns:formsUtils="clr-namespace:FlyMasterSyncGui.FormsUtils"
    Title="FlymasterSync" Height="372" Width="608"
    Icon="../Assets/icon.ico"
    WindowStartupLocation="CenterScreen"
    Closed="FlightLog_OnClosed"
    Closing="FlightLog_OnClosing" Loaded="FlightLog_OnLoaded">

<Window.Resources>

    <CollectionViewSource x:Key="groupedFlights" Source="{Binding TracksDb.Entries}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="FlightInfo.Date" Converter="{formsUtils:YearConverter}" />
            <PropertyGroupDescription PropertyName="FlightInfo.Date" Converter="{formsUtils:MonthConverter}" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>

    <DataTemplate x:Key="InnerTemplate">
        <Grid Margin="0,10,0,0">
            <Border VerticalAlignment="Bottom" Background="#FF9CA7B4" 
Padding="5,0,0,0"> 
[...]

不过,在此 xaml 中,我使用了一些 ValueConverter,经过一些尝试后我发现是 MonthConverter 触发了异常。转换器代码如下:

public class MonthConverter : MarkupExtension, IValueConverter
{
    private MonthConverter _converter;

    public MonthConverter()
    {
    }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        DateTime d = (DateTime)value;

        //Exception Here
        var monthName = CultureInfo.GetCultureInfo("en-en").DateTimeFormat.GetMonthName(d.Month);                         
        return char.ToUpper(monthName[0]) + monthName.Substring(1);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (_converter == null) _converter = new MonthConverter();
        return _converter;
    }
}

我调用时出现异常:

CultureInfo.GetCultureInfo("en-en").DateTimeFormat.GetMonthName(d.Month);

我真的不明白为什么。 目前我只是创建了一个将月份数字转换成它的名称的自定义函数,所以我不需要调用 CultureInfo 并且我解决了这个问题,但我想知道为什么会触发这个异常以及为什么它只会发生在 Windows 7. xaml 在 Windows 7 中的解析方式不同吗? Window 7 以后是否加载 CultureInfo 数据?

提前感谢您的回复:)

在 Windows 7 中 CultureInfo.GetCultureInfo("en-en") 抛出一个 CultureNotFoundException。尝试使用简单的 en 或区域特定的文化,例如 en-US。但是,在与字符串相互转换时,我会使用 CultureInfo.InvariantCulture

在此处查看可用的区域性名称:http://www.csharp-examples.net/culture-names/