问题描述
我的应用程序正在生成一些RDLC报告,其中包括日期字段。我想使用“区域和语言”控制面板中用户的首选设置来显示此日期字段(您可能会认为这是默认行为,但显然不是)。
报告文本框使用一种特定于语言环境的格式设置为日期格式-在属性中以D
格式显示。
我的应用程序尚未更改Thread.CurrentThread.CurrentCulture
。在我自己的代码中(显示报告之前或之后)运行DateTime.Now.ToString("D")
时,它的行为与更改控制面板设置时的预期一致:
- 设置为“英语(NZ)”和默认的长日期格式,我得到
Friday,16 October 2020
。 - 设置为“英语(NZ)”和其他长日期格式,我得到
16 October 2020
。 - 设置为“法国(法国)”和默认的长日期格式,我得到
vendredi 16 octobre 2020
。 - 设置为“法国(法国)”并使用其他长日期格式,我得到
16 octobre 2020
。
但是,当我查看报告时,尽管我确实得到了预期的默认格式或备用格式,但报告始终以英文显示(与所选区域无关)。
仔细阅读后,我发现默认行为显然是不正确的,您必须将报告语言显式设置为=User!Language
,以使其服从语言设置(并且声称可以使用{ {1}}),但是这样做之后,它现在可以正确地遵循该语言,但是无论控制面板如何设置,它都只会使用默认格式,而不会使用替代格式。这是一个改进,但仍然不正确。
如何使报表查看器的行为类似于常规.NET CurrentCulture
,并实际使用当前的区域性?我不想在报告中硬编码任何特定的语言或格式。
我当前正在使用ToString()
。
解决方法
好的,这有点邪恶,但是直到微软修复了他们的错误,我看不到其他选择。
- 请确保不将报告的语言设置为
=User!Language
(除非您要对该特定报告强制使用特定的非默认值,否则根本不要设置语言)。 - 将Lib.Harmony NuGet软件包添加到您的项目中。 (下面的代码假设您使用的是1.2;您可能需要对其稍作调整以获取更高版本。)
- 添加以下类:
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;
}
}
- 在应用启动时尽早致电
ReportViewerBugFix.Patch()
。
(对于额外的妄想症,您可以在调用CultureInfo.CurrentCulture
时捕获Patch
并返回该值,而不用稍后再查询它。但是以上情况在所有情况下都是按原样工作的我尝试过的。)
这会将DefaultReportServerSpecificCulture
的返回值更改为与ClientPrimaryCulture
相同,因为在外部补丁程序中,这样做比使EvaluateReportLanguage
调用正确的事物更容易(这将通过访问代码可能是更好的解决方案)。但这没关系,因为您绝对没有理由首先要使用Windows UI语言。