繁体   English   中英

vsto:c#在运行时更改Excel UI对象(例如功能区)的本地化

[英]vsto: c# change localization of Excel UI objects, e.g. ribbon, at runtime

我发现了一些有关更改Windows窗体的本地化的线程,但没有对功能区或Excel的其他UI元素执行相同的操作。 我的VS 2013中没有My.Application.SetCulture (不知道为什么)。

  1. Windwos表单:运行时本地化
  2. 在VSTO插件中设置CurrentCulture
  3. Windwos窗体:在运行时更改语言的正确方法

我花了一段时间来接受VSTO的界限,但是我编写了一个可接受的解决方法。 但是首先我遇到的限制

  1. Office应用程序在运行时无法更改文化。 如果使用Microsoft Office语言工具来更改用户界面语言,则可以看到这一点。
    您将始终收到一条消息,指出更改必须在Office应用程序关闭并重新启动后才能进行。 来源

    听起来很合理,至少我没有找到任何不同意的条目,而我发现的所有MSDN条目都仅在启动AddIn之前提到了设置本地设置

  2. 似乎没有任何功能区对象集合。 这意味着,如果有多个功能区(取决于操作系统或情况),则无法遍历所有功能区。 由于您仍然不能同时使用多个功能区(但您可以选择在运行时显示哪些功能区 ),根据此MSDN条目 ,Outlook加载可能会被关闭。

  3. 您不能更改单个选项卡的语言使其刷新所有包含的控件。 您必须在每一层上逐个执行Tab-> Group-> Items

最后是我的代码。 我有两个单独的类,一个用于重新定位任何打开的窗体,另一个用于AddIn。 两者基本上都遍历了表单中的所有对象以及特定功能区的所有选项卡,并更改了每个对象的语言资源。 在经历了所有这些限制之后,它的工作效果出奇地好。 我唯一不了解的是,为什么必须将对功能区的引用作为Microsoft.Office.Tools.Ribbon.RibbonBase类型传递给类cs_RuntimeLocalizer4OfficeUI

private void Bt_LocalDE_Click(object sender, ToolsRibbon.RibbonControlEventArgs e)
        {
            changeUICulture("de-DE");
        }

        private void Bt_LocalEN_Click(object sender, ToolsRibbon.RibbonControlEventArgs e)
        {
            changeUICulture("en-GB");
        }

        private void changeUICulture(string cultureCode)// (Control parent, CultureInfo culture)       //https://stackoverflow.com/questions/11711426/proper-way-to-change-language-at-runtime
        {
            cs_RuntimeLocalizer4OfficeUI.ChangeCulture(this, cultureCode);
            foreach (WinForms.Form OpenForm in WinForms.Application.OpenForms)  //based on https://hashfactor.wordpress.com/2009/01/28/c-check-if-a-form-is-already-opened/
            {
                cs_RuntimeLocalizer4Forms.ChangeCulture(OpenForm, cultureCode);
            }
        }

    }

cs_RuntimeLocalizer4OfficeUI

using OToolsRibbon = Microsoft.Office.Tools.Ribbon;
using System.Globalization;
using System.Threading;
using System.ComponentModel;

using SysDiag = System.Diagnostics;

namespace Pro_Wunderkiste4Excel
{
    static class cs_RuntimeLocalizer4OfficeUI    //based on https://stackoverflow.com/questions/6980888/localization-at-runtime since relocalization after startup is not possible according to https://www.gittprogram.com/question/1159277_cultureinfo-currentculture.html
    {
        public static void ChangeCulture(OToolsRibbon.RibbonBase ri_Ribbon, string cultureCode)
        {
            CultureInfo culture = CultureInfo.GetCultureInfo(cultureCode);  //http://www.csharp-examples.net/culture-names/
            Thread.CurrentThread.CurrentUICulture = culture;
            ComponentResourceManager resources = new ComponentResourceManager(ri_Ribbon.GetType());

            foreach (OToolsRibbon.RibbonTab ri_Tab in ri_Ribbon.Tabs)    //based on http://www.devcomponents.com/kb2/?p=696
            {
                resources.ApplyResources(ri_Tab, ri_Tab.Name, culture);
                foreach (OToolsRibbon.RibbonGroup ri_TabGroups in ri_Tab.Groups)    //based on https://stackoverflow.com/questions/7824125/better-way-to-programmatically-lock-disable-multiple-ui-controls-on-ribbon-bar
                {
                    resources.ApplyResources(ri_TabGroups, ri_TabGroups.Name, culture);
                    foreach (OToolsRibbon.RibbonControl ri_TabGroupsCtrl in ri_TabGroups.Items)
                    {
                        SysDiag.Debug.Print(ri_TabGroupsCtrl.Name);
                        resources.ApplyResources(ri_TabGroupsCtrl, ri_TabGroupsCtrl.Name, culture);
                    }
                }
            }

        }
    }
}

类cs_RuntimeLocalizer4Forms

using System.Windows.Forms;
using System.Globalization;
using System.Threading;
using System.ComponentModel;

namespace Pro_Wunderkiste4Excel
{
    static class cs_RuntimeLocalizer4Forms //based on https://stackoverflow.com/questions/6980888/localization-at-runtime and https://stackoverflow.com/questions/3558406/how-to-change-language-at-runtime-without-layout-troubles
    {

        public static void ChangeCulture(Form frm, string cultureCode)
        {
            CultureInfo culture = CultureInfo.GetCultureInfo(cultureCode);  //http://www.csharp-examples.net/culture-names/

            Thread.CurrentThread.CurrentUICulture = culture;

            ComponentResourceManager resources = new ComponentResourceManager(frm.GetType());

            ApplyResourceToControl(resources, frm, culture);
            resources.ApplyResources(frm, "$this", culture);
        }

        private static void ApplyResourceToControl(ComponentResourceManager res, Control control, CultureInfo lang)
        {
            if (control.GetType() == typeof(MenuStrip))  // See if this is a menuStrip
            {
                MenuStrip strip = (MenuStrip)control;

                ApplyResourceToToolStripItemCollection(strip.Items, res, lang);
            }

            foreach (Control c in control.Controls) // Apply to all sub-controls
            {
                ApplyResourceToControl(res, c, lang);
                res.ApplyResources(c, c.Name, lang);
            }

            // Apply to self
            res.ApplyResources(control, control.Name, lang);
        }

        private static void ApplyResourceToToolStripItemCollection(ToolStripItemCollection col, ComponentResourceManager res, CultureInfo lang)
        {
            for (int i = 0; i < col.Count; i++)     // Apply to all sub items
            {
                ToolStripItem item = (ToolStripMenuItem)col[i];

                if (item.GetType() == typeof(ToolStripMenuItem))
                {
                    ToolStripMenuItem menuitem = (ToolStripMenuItem)item;
                    ApplyResourceToToolStripItemCollection(menuitem.DropDownItems, res, lang);
                }

                res.ApplyResources(item, item.Name, lang);
            }
        }
    }
}

如果您要按此处所述根据操作系统或Office语言设置语言,则可能会对“ 本地ID”表感兴趣

另一种方法可能适用于多个插件。 其中之一仅加载/卸载必须更改其语言的插件

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM