如何使 RDLC 使用控制面板中的日期格式

How to make RDLC use date format from control panel

我的应用正在生成一些 RDLC 报告,其中包含一个日期字段。我想使用区域和语言控制面板中用户的首选设置来显示此日期字段(您可能认为这是默认行为,但显然不是)。

报告文本框被格式化为使用一种特定于语言环境的格式的日期——在属性中它显示为格式 D

我的应用程序没有更改 Thread.CurrentThread.CurrentCulture。当我在自己的代码中 运行 DateTime.Now.ToString("D") 时(在显示报告之前或之后),当我更改控制面板设置时,它的行为与我预期的一样:

然而,当我查看报告时,它总是以英文显示(无论选择哪个区域),尽管我确实得到了预期的默认或替代格式。

仔细阅读,我发现默认行为显然是不正确的,您必须将报告语言明确设置为 =User!Language 以使其遵守语言设置(据称这是为了使其使用CurrentCulture) -- 但是在这样做之后,它现在正确地遵循语言但只使用默认格式,从不使用备用格式,无论控制面板设置如何。这是一个改进,但仍然不正确。

如何让报表查看器的行为像常规 .NET ToString() 一样,并实际使用当前区域性?我不想在报告中硬编码任何特定的语言或格式。

我目前正在使用 Microsoft.ReportingServices.ReportViewerControl.Winforms.150.1404.0.nupkg

好吧,这有点邪恶,但在 Microsoft 修复他们的错误之前我看不到任何替代方案。

  1. 确保报告没有将语言设置为=User!Language(并且根本不要设置语言,除非你想强制特定non-defaults对于那个特定的报告)。
  2. Lib.Harmony NuGet 包添加到您的项目中。 (下面的代码假定您使用的是 1.2;您可能需要为更高版本稍微调整它。)
  3. 添加以下内容class:
    public static class ReportViewerBugFix
    {
        public static void Patch()
        {
            HarmonyInstance.Create("fix.broken.microsoft.reportviewer").Patch(
                AccessTools.Method("Microsoft.ReportingServices.Diagnostics.Localization,Microsoft.ReportViewer.Common:get_DefaultReportServerSpecificCulture"),
                prefix: new HarmonyMethod(AccessTools.Method(typeof(ReportViewerBugFix), nameof(PatchDefaultReportServerSpecificCulture))));
        }

        private static bool PatchDefaultReportServerSpecificCulture(ref CultureInfo __result)
        {
            __result = CultureInfo.CurrentCulture;
            return false;
        }
    }
  1. 在您的应用程序启动早期调用 ReportViewerBugFix.Patch()

(对于额外的偏执狂,您可以在调用 Patch 时捕获 CultureInfo.CurrentCulture 并且 return 该值而不是 re-querying 稍后。但是上面我试过的所有案例都工作 as-is。)

这会将 DefaultReportServerSpecificCulture 的 return 值更改为与 ClientPrimaryCulture 相同,因为在外部补丁中这样做比让 EvaluateReportLanguage 调用相反,正确的事情(这可能是更好的解决方案,可以访问代码)。但这没关系,因为您绝对没有理由首先要使用 Windows UI 语言。