根据Office产品的语言本地化VSTO插件

5

我正在开发一个VSTO插件,希望根据Office产品的语言版本进行本地化。理论上,以下是如何实现:

int lcid = Application.LanguageSettings.get_LanguageID(Office.MsoAppLanguageID.msoLanguageIDUI);
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lcid);

为了使这个工作,我需要初始化Application。所以我能执行这段代码的最早时间是在启动事件处理程序中。然而,在这一点上,CreateRibbonExtensibilityObject()已经被调用,因此我的自定义功能区选项卡的标题至少会显示为Windows语言,这可能是不同的。
在功能区类中,我有一个onLoad事件处理程序,可以在其中存储IRibbonUI的实例以供以后使用。我可以将此实例交给插件类,并让其调用IRibbonUI.Invalidate()。但这似乎有点奇怪——创建一个功能区只是为了在几微秒后使其无效。所以我想知道——并在这里询问——是否有一种更优雅的方式根据Office产品的语言版本本地化vsto插件的功能区。
(我看到了这个类似的问题,但那里提供的方法在我看来更糟糕。

回复:更糟糕的方法:你指的当然是注册表查找,对吧?建议使用CurrentUICulture的答案对我来说很有道理。 - Ishmaeel
1
@Ishmaeel 当然。那个答案比我的问题更新。我刚刚编辑了那部分以使其清晰明了。我的第一次尝试(请参见问题)以及那个新答案和此处接受的答案都设置了CurrentUICulture。它们在从哪里获取上有所不同。 - Matthias
1个回答

9
您可以始终覆盖CreateRibbonExtensibilityObject方法,或者可能覆盖一些其他AddInBase方法(BeginInit、Initialize等),以便在AddIn加载生命周期的适当位置进行挂钩。
我以前曾覆盖CreateRibbonExtensibilityObject,以确保在加载Ribbon之前运行初始化代码。我注意到CreateRibbonExtensibilityObjectStartup事件会在随机时间触发。有时先发生Startup - 有时先触发CreateRibbonExtensibilityObject。我必须手动同步这两个事件,以确保在创建Ribbon之前执行任何初始化代码。如果先触发CreateRibbonExtensibilityObject - Application对象尚未创建。
请尝试在CreateRibbonExtensibility中使用此方法:
 Outlook.Application app = this.GetHostItem<Outlook.Application>(typeof(Outlook.Application), "Application");
 int lcid = app.LanguageSettings.get_LanguageID(Office.MsoAppLanguageID.msoLanguageIDUI);
 Thread.CurrentThread.CurrentUICulture = new CultureInfo(lcid);

这将为您检索对Application实例的引用 - 无论它是否已在Initialize中加载。

CreateRibbonExtensibilityObject是从ThisAddIn.Initialize中调用的(在调用堆栈中有几个方法) - 它由base.Initialize()触发,就在设置Application的行之前。我不明白线程同步如何帮助这里。我在执行ThisAddIn.Initialize的同一线程中。要到达设置Application的行(在生成的代码中,我不想去碰它),我需要从CreateRibbonExtensibilityObject返回。 - Matthias
你是使用Ribbon Designer还是Ribbon XML来设计Fluent UI? - SliverNinja - MSFT
1
谢谢 - 对我也有效。你知道有没有比MSDN页面更详细的GetHostItem<T>()文档?否则,我只能乐观地假设它像其“Get”前缀所承诺的那样轻量级... - Matthias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接