Winformプログラムの多言語サポートを実現する複数のソリューションを共有します。
会社の業務の需要のため、既存のERPシステムを加えて繁体語をサポートする必要がありますが、既存のコード方式を変えることはできません。つまり、普通のプログラマはコードの違いを感じられません。いくつかの同僚とのマルチコミュニケーションを経て、以下の二つの案を確定しました。
プログラム1:フォームベースクラスでフォームをロードして表示するたびに、テキスト表示を含むコントロール(Button、CheckBox、GroupBox、Label、LinkLabel、TextBox、SttusStrip、TabPage、ToolStrip、RadiButtoton、DateTimePicker、DataGradLiew、Stred View、Stripコントロールの種類に応じてテキスト属性を呼び出し、簡単な変換方法を呼び出して、新しいテキスト属性の内容を変換して設定し直します。
利点:符号化は簡単で、普通のプログラマの符号化には影響がありません。
短所:フォームを開くたびにコントロールを巡回して簡単に変換する必要がありますので、もし界面のコントロールが多いと、フォームのオープンが遅くなり、ユーザーの体験に影響を与えます。また、サブコントロールのテキストの内容が変更されると、プログラマが手動で通知して、自動的に感知できなくなります。
具体的な実現の考えは以下の通りです。
一.Formクラスを二次パッケージ(継承)し、MyStyle FormBaseクラスを定義し、フォームタイプをロードして表示するたびに、自動的にテキスト表示のコントロールを巡回し、コントロールタイプのテキスト属性に応じて簡単な変換方法を呼び出して、新しいテキスト属性の内容を再設定します。このように、すべてのフォームがMyStyle FormBaseクラスを継承する場合、デフォルトでは遍歴と変換のプロセスが実現され、プログラマは再コードする必要がなく、遍歴と変換のプロセスがあることを知る必要もなく、コードの多重性が向上します。具体的なコードは以下の通りです。
1.現在のUIの文化領域が中国語簡体字でない場合(本プログラム自体はすべて簡体字に基づいて開発されているので)、フォームを購読してイベントShownとフォームのタイトルを表示してイベントTextChendを変更します。
2.フォームが表示された後にフォームのコントロールを購読すると、イベントのControl Addedが増加します。役割:フォームが表示された後、コードが続いてコントロールが追加された場合、コントロールとそのサブコントロールは自動的に繁体字変換され、一つも漏れないようにします。
3.メッセージメッセージを表示する枠を追加する方法は、メッセージウィンドウをイジェクトする前に簡体字テキストを繁体字テキストに変換することができることを目的とする。
4.サブコントロール変更メッセージを強制的に通知する方法PerformChildren Changeを追加し、あるコントロールのテキストコンテンツまたはサブコントロールの追加が発生した場合、フォーム自体がキャプチャできないため、この方法を呼び出してサブコントロールのテキストコンテンツを遍歴する必要があります。ここはあまり良くないと思いますが、今はもっといい方法がありません。もしもっといい方法があれば、コメントを歓迎します。
二、Languaghelper:言語側変換公共類(現在は単純な変換のみをサポートしています。Chinese Converter.dllに依存しています。)コードは以下の通りです。
コードが長すぎますので、ダウンロードをお願いします。
このクラスのロジックは、親コントロールからすべてのサブコントロールを遍歴し、コントロールの種類に応じてテキスト内容を簡体字または繁体字に変換します。
以上の二段階で多言語のサポートが実現されました。プロジェクトに適用するのは簡単です。フォームのデフォルトの基本タイプのFormを変更するだけでいいです。public partial class FormTest:MyStyle FormBase。
シナリオ2:コントロールによって、現在のエリア情報+キャッシュ言語辞書に基づいて、直接に各コントロールの自己変換を実現します。
利点:巡回する必要はなく、各コントロールは自分で地域情報に基づいて自己サポート変換します。したがって、効率が高く、一般プログラマのコードには影響がありません。
短所:テキスト付きのすべてのコントロール(例えば、Button、CheckBox、GroupBox、Label、LinkLabel、Text Box、Sttus Strip、TabPage、ToolStrip、Radio Button、DateTimePicker、DataGred View、CheckedListx、Steeewという名前のコントロールが統一されています。)
関連するコントロールが多く、コードが複雑です。
具体的な実現の考えは以下の通りです。
一.Form類を二次パッケージ(継承)し、MyStyle FormBase類を定義し、フォームのタイトルを修正する時に追加して、自動的に多言語変換機能ができます。具体的なコードは以下の通りです。
二.多言語対応の一般コントロールとコンテナコントロールインターフェース(IMultiLanguagontrol、IMultiLanguage ContinerControl)を定義し、具体的なコードは以下の通りである。
以下はMyStyle Button定義コード、MyStyle CheckBox、MyStyle GroupBox、MyStyle Label、MyStyle LinkLabel、MyStyle TextBox、MyStyle Radio Buttonの中の実現コードは同じです。
四、マルチ言語コンテナコントロールのサポートを実現する:既存の標準コントロールに基づいて二次パッケージを行い、IMultiLanguage ConterControlインターフェースを実現します。各コントロールコードは以下の通りです。
MyStyle Data GridView:
コードが長すぎますので、ダウンロードをお願いします。
MyStyle TabControl:
コードが長すぎますので、ダウンロードをお願いします。
これらのコントロールを二次的にカプセル化する目的は、1.統一された属性を暴露し、直接的に遍歴し、値を付与するのに便利である(テキストの内容言語を直接変更する場合のみ必要である)。2.テキストの内容またはサブコントロールのテキストの内容またはサブコントロールの追加によって変更が発生した場合、言語キャッシュ辞書によって、迅速で直接的な自己単純変換が可能であり、再度巡回する必要がない。
五.Languaghelper:言語側変換公共類は、方案の原理と同じであるが、相対案は簡単で多く、コードは以下の通りである。
コードが長すぎますので、ダウンロードをお願いします。
Common.Is Chs Language方法の定義は以下の通りです。
以上が本文の全部の内容です。なぜ資源書類の形式を採用しないのかというと、原因は文章の冒頭から説明されています。元のシステム上で、しかも元のコードスタイルを変えることができないので、こんなに大きな力を使ってこの簡単な転換の機能を実現することができました。もし足りないところがあれば、交流を歓迎します。ありがとうございます。
注:コントロールの実現コードは全部貼り付けました。必要なら、直接COPYに行ってもいいです。また、システムの安全のために、簡繁体字のシステムのスクリーンショットは貼り付けません。みんな自分でテストしてもいいです。
プログラム1:フォームベースクラスでフォームをロードして表示するたびに、テキスト表示を含むコントロール(Button、CheckBox、GroupBox、Label、LinkLabel、TextBox、SttusStrip、TabPage、ToolStrip、RadiButtoton、DateTimePicker、DataGradLiew、Stred View、Stripコントロールの種類に応じてテキスト属性を呼び出し、簡単な変換方法を呼び出して、新しいテキスト属性の内容を変換して設定し直します。
利点:符号化は簡単で、普通のプログラマの符号化には影響がありません。
短所:フォームを開くたびにコントロールを巡回して簡単に変換する必要がありますので、もし界面のコントロールが多いと、フォームのオープンが遅くなり、ユーザーの体験に影響を与えます。また、サブコントロールのテキストの内容が変更されると、プログラマが手動で通知して、自動的に感知できなくなります。
具体的な実現の考えは以下の通りです。
一.Formクラスを二次パッケージ(継承)し、MyStyle FormBaseクラスを定義し、フォームタイプをロードして表示するたびに、自動的にテキスト表示のコントロールを巡回し、コントロールタイプのテキスト属性に応じて簡単な変換方法を呼び出して、新しいテキスト属性の内容を再設定します。このように、すべてのフォームがMyStyle FormBaseクラスを継承する場合、デフォルトでは遍歴と変換のプロセスが実現され、プログラマは再コードする必要がなく、遍歴と変換のプロセスがあることを知る必要もなく、コードの多重性が向上します。具体的なコードは以下の通りです。
public class MyStyleFormBase : Form
{
public MyStyleFormBase()
{
if (!Thread.CurrentThread.CurrentUICulture.Name.Equals("zh-CHS", StringComparison.OrdinalIgnoreCase)) // ,
{
base.TextChanged += MyStyleFormBase_TextChanged;
base.Shown += MyStyleFormBase_Shown;
}
}
private void MyStyleFormBase_TextChanged(object sender, EventArgs e)
{
this.Text = LanguageHelper.GetLanguageText(this.Text);
}
private void MyStyleFormBase_Shown(object sender, EventArgs e)
{
LanguageHelper.SetControlLanguageText(this);
base.ControlAdded += MyStyleFormBase_ControlAdded;
}
private void MyStyleFormBase_ControlAdded(object sender, ControlEventArgs e)
{
LanguageHelper.SetControlLanguageText(e.Control);
}
/// <summary>
///
/// </summary>
/// <param name="target"></param>
protected virtual void PerformChildrenChange(Control target)
{
LanguageHelper.SetControlLanguageText(target);
}
/// <summary>
///
/// </summary>
/// <param name="text"></param>
/// <param name="caption"></param>
/// <param name="buttons"></param>
/// <param name="icon"></param>
/// <param name="defaultButton"></param>
/// <returns></returns>
protected DialogResult MessageBoxShow(string text, string caption, MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon icon = MessageBoxIcon.None, MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1)
{
return MessageBox.Show(LanguageHelper.GetLanguageText(text), LanguageHelper.GetLanguageText(caption), buttons, icon, defaultButton);
}
}
コードロジックの簡単な説明:1.現在のUIの文化領域が中国語簡体字でない場合(本プログラム自体はすべて簡体字に基づいて開発されているので)、フォームを購読してイベントShownとフォームのタイトルを表示してイベントTextChendを変更します。
2.フォームが表示された後にフォームのコントロールを購読すると、イベントのControl Addedが増加します。役割:フォームが表示された後、コードが続いてコントロールが追加された場合、コントロールとそのサブコントロールは自動的に繁体字変換され、一つも漏れないようにします。
3.メッセージメッセージを表示する枠を追加する方法は、メッセージウィンドウをイジェクトする前に簡体字テキストを繁体字テキストに変換することができることを目的とする。
4.サブコントロール変更メッセージを強制的に通知する方法PerformChildren Changeを追加し、あるコントロールのテキストコンテンツまたはサブコントロールの追加が発生した場合、フォーム自体がキャプチャできないため、この方法を呼び出してサブコントロールのテキストコンテンツを遍歴する必要があります。ここはあまり良くないと思いますが、今はもっといい方法がありません。もしもっといい方法があれば、コメントを歓迎します。
二、Languaghelper:言語側変換公共類(現在は単純な変換のみをサポートしています。Chinese Converter.dllに依存しています。)コードは以下の通りです。
コードが長すぎますので、ダウンロードをお願いします。
このクラスのロジックは、親コントロールからすべてのサブコントロールを遍歴し、コントロールの種類に応じてテキスト内容を簡体字または繁体字に変換します。
以上の二段階で多言語のサポートが実現されました。プロジェクトに適用するのは簡単です。フォームのデフォルトの基本タイプのFormを変更するだけでいいです。public partial class FormTest:MyStyle FormBase。
シナリオ2:コントロールによって、現在のエリア情報+キャッシュ言語辞書に基づいて、直接に各コントロールの自己変換を実現します。
利点:巡回する必要はなく、各コントロールは自分で地域情報に基づいて自己サポート変換します。したがって、効率が高く、一般プログラマのコードには影響がありません。
短所:テキスト付きのすべてのコントロール(例えば、Button、CheckBox、GroupBox、Label、LinkLabel、Text Box、Sttus Strip、TabPage、ToolStrip、Radio Button、DateTimePicker、DataGred View、CheckedListx、Steeewという名前のコントロールが統一されています。)
関連するコントロールが多く、コードが複雑です。
具体的な実現の考えは以下の通りです。
一.Form類を二次パッケージ(継承)し、MyStyle FormBase類を定義し、フォームのタイトルを修正する時に追加して、自動的に多言語変換機能ができます。具体的なコードは以下の通りです。
public partial class MyStyleFormBase : Form
{
public MyStyleFormBase()
{
base.TextChanged += MyStyleFormBase_TextChanged;
}
private void MyStyleFormBase_TextChanged(object sender, EventArgs e)
{
if (!Common.IsChsLanguage())
{ this.Text = LanguageHelper.GetLanguageText(this.Text); }
}
/// <summary>
///
/// </summary>
/// <param name="text"></param>
/// <param name="caption"></param>
/// <param name="buttons"></param>
/// <param name="icon"></param>
/// <param name="defaultButton"></param>
/// <returns></returns>
protected DialogResult MessageBoxShow(string text, string caption = " ", MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon icon = MessageBoxIcon.None, MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1)
{
if (!Common.IsChsLanguage())
{
text = LanguageHelper.GetLanguageText(text);
caption = LanguageHelper.GetLanguageText(caption);
}
return MessageBox.Show(text, caption, buttons, icon, defaultButton);
}
}
コードロジックは簡単です。つまりForm.TextChangedイベントを購読して、IsChs Language(簡体字モードかどうかを判断します。)によって簡体ではないと判断する場合、Form.Text変換を行います。二.多言語対応の一般コントロールとコンテナコントロールインターフェース(IMultiLanguagontrol、IMultiLanguage ContinerControl)を定義し、具体的なコードは以下の通りである。
/// <summary>
/// ( )
/// </summary>
public interface IMultiLanguageControl
{
string DefaultLangText { get; }
string CurrentLangText { get; set; }
}
/// <summary>
/// ( )
/// </summary>
public interface IMultiLanguageContainerControl
{
Dictionary<object, string> DefaultLangTexts { get; }
Dictionary<object, string> CurrentLangTexts { get; set; }
Control this[string ctrlName] { get; set; }
void SetItemCurrentLangText(string ctrlName, string langText);
event EventHandler<ChildrenAddedEventArgs> ChildrenChanged;
}
public class ChildrenAddedEventArgs : EventArgs
{
public Dictionary<object, string> LangTexts { get; private set; }
public ChildrenAddedEventArgs()
{
LangTexts = new Dictionary<object, string>();
}
public ChildrenAddedEventArgs(Dictionary<object, string> langTexts)
{ this.LangTexts = langTexts; }
public string this[object key]
{get
{
return LangTexts[key];
}
set
{
LangTexts[key] = value;
} }}
三、多言語普通コントロールのサポートを実現する:既存の標準コントロール(Button、CheckBox、GroupBox、Label、LinkLabel、TextBox、Radio Button、DateTimePicker)に基づいて二次パッケージを行い、IMultiLanguage Controlインターフェースを実現します。各コントロールコードは以下の通りです。以下はMyStyle Button定義コード、MyStyle CheckBox、MyStyle GroupBox、MyStyle Label、MyStyle LinkLabel、MyStyle TextBox、MyStyle Radio Buttonの中の実現コードは同じです。
public partial class MyStyleButton : MyButton, IMultiLanguageControl
{
static Dictionary<string, string> LanDict = new Dictionary<string, string>();
public MyStyleButton()
{ }
public override string Text
{
get
{
if (!DesignMode && System.Threading.Thread.CurrentThread.CurrentUICulture.Name != "zh-CHS")
{
if (LanDict.ContainsKey(DefaultLangText))
{
return CurrentLangText;
}
else
{
string langText = LanguageHelper.GetLanguageText(base.Text);
LanDict[base.Text] = langText;
return langText;
}
}
return base.Text;
}
set
{
base.Text = value;
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string DefaultLangText
{
get
{
return base.Text;
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string CurrentLangText
{
get
{
try
{
return LanDict[DefaultLangText];
}
catch (Exception)
{
return "";
}
}
set
{
if (System.Threading.Thread.CurrentThread.CurrentUICulture.Name != "zh-CHS")
{
if (LanDict.ContainsKey(DefaultLangText))
{
LanDict[DefaultLangText] = value;
}
else
{
LanDict.Add(DefaultLangText, value);
}
}
}
}
}
これらのコントロールを二次的にカプセル化する目的は、1.統一された属性を暴露し、直接的に遍歴し、値を付与するのに便利である(テキストの内容言語を手動で変更する必要がある場合)。2.テキストの内容が変更された場合、言語キャッシュ辞書によって、迅速かつ直接的な自己繁雑変換ができます。四、マルチ言語コンテナコントロールのサポートを実現する:既存の標準コントロールに基づいて二次パッケージを行い、IMultiLanguage ConterControlインターフェースを実現します。各コントロールコードは以下の通りです。
MyStyle Data GridView:
コードが長すぎますので、ダウンロードをお願いします。
MyStyle TabControl:
コードが長すぎますので、ダウンロードをお願いします。
これらのコントロールを二次的にカプセル化する目的は、1.統一された属性を暴露し、直接的に遍歴し、値を付与するのに便利である(テキストの内容言語を直接変更する場合のみ必要である)。2.テキストの内容またはサブコントロールのテキストの内容またはサブコントロールの追加によって変更が発生した場合、言語キャッシュ辞書によって、迅速で直接的な自己単純変換が可能であり、再度巡回する必要がない。
五.Languaghelper:言語側変換公共類は、方案の原理と同じであるが、相対案は簡単で多く、コードは以下の通りである。
コードが長すぎますので、ダウンロードをお願いします。
Common.Is Chs Language方法の定義は以下の通りです。
public static bool IsChsLanguage()
{
return System.Threading.Thread.CurrentThread.CurrentUICulture.Name.Equals("zh-CHS", StringComparison.OrdinalIgnoreCase);
}
多言語でサポートされているコンテナコントロールの実現の難しさは、サブコントロールのテキスト内容の変更をキャプチャすることであり、既成のイベントや方法がないため、他の方法でテキスト内容の変更を実現する必要がある場合には処理が可能となります。以上が本文の全部の内容です。なぜ資源書類の形式を採用しないのかというと、原因は文章の冒頭から説明されています。元のシステム上で、しかも元のコードスタイルを変えることができないので、こんなに大きな力を使ってこの簡単な転換の機能を実現することができました。もし足りないところがあれば、交流を歓迎します。ありがとうございます。
注:コントロールの実現コードは全部貼り付けました。必要なら、直接COPYに行ってもいいです。また、システムの安全のために、簡繁体字のシステムのスクリーンショットは貼り付けません。みんな自分でテストしてもいいです。