تعدد اللغات في تطبيقات WinForms/WPF ── الممارسة العملية لملفات resx وتجميعات الأقمار الصناعية وتبديل الثقافة
· آخر تحديث: · غو كومورا · CSharp, .NET, WinForms, WPF, تعدد اللغات, التوطين, الموارد, UI, تطوير Windows, الاستشارة التقنية
سجل التعديلات (2 تحديثات، آخر تحديث 2 Sep، 2026)
سجل بالتغييرات التي أُجريت على هذا المقال. وحيثما حُفظت نسخة سابقة، تبقى متاحة للقراءة عبر رابط دائم يحمل معرّف DOI.
- أُعيدَت الترجمة العربية كترجمة كاملة عن النص الياباني الأصلي، وأُضيفَت خريطة المعرفة.
- أعيدت الترجمة كترجمة كاملة عن النص الياباني الأصلي. كانت النسخة العربية السابقة مختصراً يسقط أبواباً وجداول ورسوم Mermaid وتعليقات الأشكال وFAQ. أُعيدت هذه العناصر وفق الأصل الياباني، والادّعاءات التقنية مطابقة للنسخة اليابانية.
- النشر الأول
الاستشهاد بهذا المقال(DOI: 10.5281/zenodo.21621674)
هذا المقال محفوظ على Zenodo. يرد أدناه معرّف DOI الذي يشير دائمًا إلى أحدث نسخة، ومعرّف DOI المثبَّت على النسخة التي تقرؤها.
غو كومورا (2026). تعدد اللغات في تطبيقات WinForms/WPF ── الممارسة العملية لملفات resx وتجميعات الأقمار الصناعية وتبديل الثقافة. شركة كومورا سوفت ذ.م.م.. https://doi.org/10.5281/zenodo.21621674 https://comcomponent.com/ar/blog/winforms-wpf-localization-guide/
- DOI (أحدث نسخة)
- 10.5281/zenodo.21621674
- DOI (هذه النسخة)
- 10.5281/zenodo.22241028
«نريد استخدام التطبيق نفسه في الفروع الخارجية أيضاً»، «ازداد عدد الموظفين الناطقين بلغات أجنبية في موقع المصنع فنريد الشاشات بالإنجليزية أيضاً» — تعدد اللغات في تطبيقات سطح المكتب على Windows مطلب بسيط في ظاهره، لكن ما إن تشرع فيه حتى تتوالى نقاط الحيرة: «كيف نستخدم resx؟»، «توجد عدة طرق في WPF ولا نعرف أيها الصحيح»، «هل يمكن تبديل اللغة أثناء التشغيل؟».
في هذا المقال، وبافتراض تطبيقات أعمال مبنية بـ WinForms/WPF، نرتّب بالترتيب الذي يكثر التردد عنده في العمل: أساس التوطين في .NET (الثقافة والرجوع الاحتياطي للموارد)، وآلية resx وتجميعات الأقمار الصناعية، والطرق الواقعية حسب كل إطار عمل، والتبديل أثناء التشغيل، حتى النقاط فيما وراء النصوص (التنسيق والتخطيط وRTL).
1. الخلاصة أولاً (جدول القرار)
طريقة تعدد اللغات تتحدد بمزيج إطار العمل والمتطلبات.
| الوضع | الطريقة الموصى بها | السبب |
|---|---|---|
| WinForms ومركز الثقل تسميات/أزرار الشاشة | Localizable = true للنموذج + resx حسب اللغة (أسلوب المصمم) |
يمكن ضبط نص عنصر التحكم وحجمه وموضعه حسب اللغة، ويكتمل الأمر في Visual Studio وحده |
| WinForms/WPF مشتركان وكثرة الرسائل والنصوص المشتركة | resx مشترك (Resources.resx + Resources.ja.resx وغيرها) + فئة مُنمَّطة مولَّدة |
يمكن الرجوع إلى السلسلة من الشيفرة بأمان نوعي. يمكن مشاركة النص نفسه بين الشاشة والمنطق |
| WPF | resx مشترك + ربط x:Static |
أسلوب LocBaml لا يعمل في WPF على .NET (Core)1. أسلوب resx يشارك المعرفة مع WinForms |
| تبديل اللغة أثناء التشغيل إلزامي | resx + آلية إشعار بالتغيير (أو إعادة إنشاء الشاشة) | قبل اختيار الطريقة أكد كمتطلب «هل التبديل بلا إعادة تشغيل لازم حقاً» (الفصل 6) |
| إسناد الترجمة إلى جهة خارجية | صمّم على أساس resx وسلّم بجدول مقابلة المفاتيح والنصوص | resx XML فيمكن تسليمه كما هو، لكن جودة العمل تتوقف على إرفاق معلومات السياق (أي زر في أي شاشة) |
نكتب الخلاصة أولاً.
CurrentCulture(التنسيق) وCurrentUICulture(لغة الموارد) شيئان مختلفان. هذا التمييز أساس تصميم تعدد اللغات كله (الفصل 2).- كيان الموارد «موارد اللغة المحايدة + تجميعات أقمار صناعية حسب اللغة»، والرجوع الاحتياطي تلقائي. يُبحث بالترتيب
ja-JP←ja← المحايد، فإن نقصت ترجمة لا يسقط التطبيق بل يُعرض بلغة الافتراضي2. - في WinForms الحل العملي الجمع بين أسلوب المصمم (
Localizable = true) وأسلوب resx المشترك. الشاشات بأسلوب المصمم، ومربعات الرسائل والنصوص المشتركة تُقرَّب إلى resx مشترك (الفصل 4). - أسلوب LocBaml الوارد في الدليل الرسمي لـ WPF لا يعمل في .NET (Core)1. الممارسة الحالية الخيار الأول resx +
x:Static(أو الربط) (الفصل 5). - تبديل اللغة أثناء التشغيل اجعل «يسري عند التشغيل التالي» خيارك الأول. لأن موارد الشاشة المعروضة لا تُستبدل تلقائياً (الفصل 6).
- ترجمة النصوص نصف تعدد اللغات فقط. النصف الباقي متابعة التخطيط لطول النص بعد الترجمة، وتنسيق التاريخ والأرقام، والخطوط، ودعم اللغات التي تُكتب من اليمين إلى اليسار (RTL) (الفصل 7).
في المخطّط، يشير الخطّ المتّصل إلى علاقة قائمة دائماً، ويشير الخطّ المتقطّع إلى علاقة مشروطة (شروط قيامها مذكورة في شرح كلّ علاقة في الصفحة التفصيليّة). القائمة الكاملة للعلاقات (المجموع 23، مع الأدلّة ودرجة اليقين) وتعريفات المفاهيم الرئيسة مجمّعة في صفحة تفاصيل خريطة المعرفة (باليابانية). البيانات: JSON-LD / Turtle
2. الأساس ── الفرق بين CurrentCulture وCurrentUICulture
لثقافة .NET (إعداد النطاق الثقافي) خاصيتان مختلفتا الدور3.
| الخاصية | ما تقرره | مثال |
|---|---|---|
CultureInfo.CurrentCulture |
تنسيق التاريخ والأرقام والعملة | العرض 2026/07/07 أم 7/7/2026 |
CultureInfo.CurrentUICulture |
أي لغة موارد تُحمَّل | ظهور «保存» على الزر أم «Save» |
يمكن ضبط الاثنتين مستقلتين. مزيج مثل «الشاشة إنجليزية، لكن التاريخ والعملة بتنسيق اليابان» (متطلب شائع في تطبيقات أعمال لناطقين بلغات أجنبية داخل اليابان) يُعبَّر عنه طبيعياً بـ CurrentUICulture = en وCurrentCulture = ja-JP.
القيمة الافتراضية لكلتيهما تأتي من إعداد نظام التشغيل، فنقطة الانطلاق «إن لم تفعل شيئاً اتبع نظام التشغيل». عند تبديل اللغة صراحة للتطبيق كله، لا تضبط حسب الخيط بل استبدل القيمة الافتراضية.
using System.Globalization;
// 以降に作られるすべてのスレッドの既定カルチャを差し替える
// (UIスレッド生成前=Application.Run前に実行する)
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en"); // リソース言語
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("ja-JP"); // 書式
الإسناد إلى Thread.CurrentThread.CurrentUICulture يسري على ذلك الخيط فقط. في تطبيق أعمال يعبر الخيوط بـ async/await أو معالجة خلفية، تغيير القيمة الافتراضية كلها بـ DefaultThreadCurrentUICulture / DefaultThreadCurrentCulture أقل عرضة للحوادث3.
لاحظ أن تنسيق السجلات وإخراج الملفات والتكامل بين الأنظمة لا تُتبع فيه ثقافة المستخدم بل يُثبَّت على CultureInfo.InvariantCulture. تصميم تنسيق التاريخ عموماً في تصميم التاريخ والوقت والمنطقة الزمنية في تطبيقات الأعمال.
3. آلية الموارد ── resx وتجميعات الأقمار الصناعية والرجوع الاحتياطي
توطين .NET نموذج «محور وأشعة». موارد اللغة الافتراضية (المحايدة) تُضمَّن في تجميعة الأصل، وموارد كل لغة تُفصل في DLL آخر اسمه تجميعة قمر صناعي4.
بعد البناء يصير تكوين الإخراج لـ resx حسب اللغة كما يلي.
MyApp.exe ← 本体(ニュートラルリソースを含む)
MyApp.dll
ja/MyApp.resources.dll ← 日本語のサテライトアセンブリ
en/MyApp.resources.dll ← 英語のサテライトアセンブリ
عند التشغيل يبحث مدير الموارد انطلاقاً من CurrentUICulture بالترتيب ثقافة محددة (ja-JP) ← ثقافة محايدة (ja) ← الافتراضي (الأصل)2. بفضل هذا الرجوع الاحتياطي التلقائي، إن نقصت ترجمة واحدة لا يسقط التطبيق بل يُعرض نص اللغة الافتراضية. وبالعكس، «شاشة يفترض أنها إنجليزية تختلط فيها يابانية في مواضع» علامة نقص ترجمة، ويمكن استخدامها كمنظور اختبار (الفصل 8).
في العمل ثبّت النقطتين التاليتين.
- التصريح بأي ثقافة هي اللغة الافتراضية بسمة
NeutralResourcesLanguageيلغي عبث البحث عن قمر صناعي عند الثقافة الافتراضية، ويوضّح نهاية الرجوع الاحتياطي4. - تجميعة القمر الصناعي «لا تعمل إلا بالتوزيع مع الأصل» لذلك يلزم تضمين مجلدات اللغة في تصميم المثبّت أو التوزيع بالنسخ (الفصل 8).
طريقة التصريح بـ NeutralResourcesLanguage اثنتان حسب شكل المشروع. أولاً الشكل القديم الذي يحمل AssemblyInfo.cs يدوياً (افتراضي .NET Framework).
// Properties/AssemblyInfo.cs
using System.Resources;
// 本体アセンブリに埋め込んだリソースが日本語であることを宣言する
[assembly: NeutralResourcesLanguage("ja-JP")]
في مشروع نمط SDK (افتراضي .NET 5 فما بعد) يُولَّد AssemblyInfo.cs عند البناء، لذلك تُحدَّد الخاصية في ملف المشروع.
<!-- MyApp.csproj -->
<PropertyGroup>
<NeutralLanguage>ja-JP</NeutralLanguage>
</PropertyGroup>
من Visual Studio يمكن الإعداد نفسه في «اللغة المحايدة للتجميعة» ضمن [الحزمة] > [عام] في خصائص المشروع. لاحظ أن كتابة الاثنين في مشروع نمط SDK تُحدث تعريفاً مزدوجاً للسمة فيصير خطأ بناء (CS0579). اجعل أحدهما فقط.
4. الممارسة في WinForms ── أسلوب المصمم وأسلوب resx المشترك
لـ WinForms أسلوبان، وفي العمل يُجمع بينهما.
4.1 الشاشات بأسلوب المصمم (Localizable = true)
في خصائص النموذج اجعل Localizable تساوي true، وبدّل خاصية Language إلى اللغة المستهدفة (مثال: الإنجليزية) ثم حرّر Text للتسميات والأزرار، فيولّد Visual Studio تلقائياً resx حسب اللغة مثل Form1.en.resx5. الخطوات بترتيب التشغيل كما يلي.
- افتح النموذج في المصمم، وانقر النموذج نفسه لا عنصر التحكم (جزء الخلفية) لاختياره
- في نافذة الخصائص (F4) اجعل
LocalizableتساويTrue. عند هذه النقطة تُكتب نصوص عناصر التحكم وأحجامها ومواضعها فيForm1.resxللغة الافتراضية - في نافذة الخصائص نفسها بدّل
Languageمن «(القيمة الافتراضية)» إلى اللغة المستهدفة (مثال: English) - في تلك الحالة حرّر
Textوحجم التسميات والأزرار وموضعها. يُحفظ التحرير فيForm1.en.resxولا يتغيّر resx اللغة الافتراضية - بعد انتهاء العمل أعد
Languageإلى «(القيمة الافتراضية)»
إن واصلت تغيير التخطيط المعتاد ناسياً الخطوة 5، دخل التغيير في resx اللغة قيد التحرير لا اللغة الافتراضية، فيُكتشف لاحقاً بشكل «موضع الزر غريب في اليابانية فقط». في الفريق الذي يستخدم أسلوب المصمم شارك نسيان إعادة Language أولاً.
قوة هذا الأسلوب أن ليس النص فقط بل حجم عنصر التحكم وموضعه يُحفظان حسب اللغة. مشكلة مثل «登録» اليابانية صارت «Register» فخرجت من الزر يمكن ضبطها حسب اللغة على المصمم. في المقابل يولد تكلفة صيانة: يزيد resx بعدد اللغات × عدد النماذج، ويلزم التحقق من كل اللغات عند كل تغيير لتخطيط النموذج. إن كان متوقعاً ازدياد عدد اللغات، قدّم تكوين شاشة «لا ينهار حتى بلا ضبط» بإجراء جانب التخطيط التالي (الفصل 7).
4.2 الرسائل والنصوص المشتركة بأسلوب resx المشترك
النصوص المستخدمة من الشيفرة مثل نص مربع الرسائل وحوار التأكيد وعرض شريط الحالة تُجمع في Resources.resx المشترك للمشروع، وتُضاف حسب اللغة ملفات مثل Resources.en.resx. من resx تُولَّد فئة مُنمَّطة تلقائياً، فيمكن الرجوع من الشيفرة بلا خطأ كتابة في المفتاح.
// 生成された型付きクラス経由で参照する。
// 返る文字列はCurrentUICultureに応じて自動で切り替わる
MessageBox.Show(
Properties.Resources.ConfirmDeleteMessage,
Properties.Resources.ConfirmTitle,
MessageBoxButtons.YesNo);
القاعدة الأهم هنا عدم كتابة النص الذي يُعرض للمستخدم مباشرة في الشيفرة. جهد تعدد اللغات لا يُنفق على إدخال الآلية بل على «استرداد النصوص المكتوبة مباشرة المتناثرة». حتى في مرحلة التشغيل بلغة واحدة، قيمة التمرير عبر resx هنا.
5. الممارسة في WPF ── اجعل resx خيارك الأول بدل LocBaml
نرتّب أولاً المصطلحات الظاهرة في هذا الفصل.
| المصطلح | القراءة / الاسم الرسمي | المعنى |
|---|---|---|
| BAML | Binary Application Markup Language | صيغة ثنائية يُترجم إليها XAML عند البناء. في تطبيق WPF لا يُحمَّل XAML نفسه بل هذا BAML المضمَّن في التجميعة عند التشغيل |
| LocBaml | — | أداة عيّنة من عصر .NET Framework تستخرج النصوص المستهدفة للترجمة من BAML وتُدخل النص المترجم وتعيد صنع BAML حسب اللغة1 |
x:Static |
— | صيغة لتحميل القيمة نفسها لخاصية أو حقل أو ثابت ثابت في جانب C# من XAML. التحميل مرة واحدة لحظة بناء الشاشة، وتغيّر القيمة لاحقاً لا يسري على الشاشة |
| تجميعة قمر صناعي | — | رمز اللغة/MyApp.resources.dll الذي يحوي موارد اللغة فقط (الفصل 3) |
تعدد اللغات في WPF مجال تختلط فيه المعلومات بسهولة. دليل الوثائق الرسمية يحمل أسلوباً يضبط UICulture في ملف المشروع ليولّد موارد BAML ثم يُدخل الترجمة بأداة LocBaml، لكن LocBaml أداة عيّنة خاصة بـ WPF على .NET Framework، ولا تعمل في WPF على .NET (Core)1. اعتبرها أسلوباً لا يُختار جديداً اليوم.
الخيار الأول في العمل الرجوع من XAML إلى أسلوب resx المشترك نفسه كما في WinForms.
<!-- resxのアクセス修飾子をPublicにしたうえでx:Staticで参照する -->
<Window xmlns:res="clr-namespace:MyApp.Properties"
Title="{x:Static res:Resources.MainWindowTitle}">
<Button Content="{x:Static res:Resources.SaveButton}" />
</Window>
ميزة هذا الأسلوب أن آلية الموارد (تجميعات الأقمار الصناعية والرجوع الاحتياطي) مشتركة تماماً مع WinForms، فيمكن إدارة النصوص مركزياً حتى في حل مختلط. x:Static مرجع ثابت يُحل عند التشغيل، فإن لزم التبديل أثناء التشغيل يُطوَّر إلى ربط + إشعار بالتغيير (الفصل 6).
في جانب XAML، اضبط أيضاً xml:lang على عنصر الجذر حتى تعمل ميزات WPF المعتمدة على اللغة مثل القطع بالشرطة والرجوع الاحتياطي للخطوط وعرض الأرقام بشكل صحيح1.
حكم الاختيار بين WinForms وWPF نفسه في جدول قرار التمييز بين WinForms / WPF / WinUI.
6. تبديل اللغة أثناء التشغيل ── اجعل «يسري عند التشغيل التالي» خيارك الأول
في متطلب اختيار اللغة من شاشة الإعدادات، اختر توقيت السريان من خطتين.
- الخطة أ: السريان عند التشغيل التالي (موصى بها). احفظ اللغة المختارة في ملف إعداد، واضبط
DefaultThreadCurrentUICultureقبلApplication.Runعند التشغيل (في WPF قبل تشغيلApplication). التنفيذ بسيط، ولا تقع بنيوياً أعطال مرافقة لإعادة بناء الشاشة (فقدان بيانات قيد الإدخال، التسجيل المزدوج لمعالج الأحداث وغيرها). - الخطة ب: السريان الفوري. حتى بعد تغيير
CurrentUICultureنصوص الشاشة المعروضة لا تُستبدل تلقائياً. في أسلوب مصمم WinForms أعد التطبيق على النماذج المفتوحة بـComponentResourceManager.ApplyResources، وفي WPF ورّد السلسلة بربط + إشعار بالتغيير. في الحالين يصير البناء شرطاً أن «كل الشاشات تدعم إعادة تطبيق الموارد».
في تطبيقات الأعمال كثيراً ما لا تتناسب تكلفة تنفيذ الخطة ب واختبارها مع تكرار تغيير اللغة (عادة مرة عند الإدخال)، فيُنصح بـ جعل الخطة أ افتراضياً، والخطة ب فقط حين تكون لازمة حقاً كمتطلب. موضع حفظ إعداد اللغة إعداد لكل مستخدم فناسب ما تحت %LOCALAPPDATA%. حكم موضع الإعداد في جدول القرار في الممارسة العملية لإدارة الإعداد في تطبيقات Windows للأعمال.
6.1 حفظ إعداد اللغة وقراءته (تنفيذ الخطة أ)
الخطة أ تكفيها شيفرة بهذا القدر. موضع الحفظ مجلد تصنعه تحت Environment.SpecialFolder.LocalApplicationData (= %LOCALAPPDATA%).
using System;
using System.Globalization;
using System.IO;
internal static class LanguageSetting
{
private static readonly string Dir = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"MyCompany", "MyApp");
private static readonly string FilePath = Path.Combine(Dir, "language.txt");
// 設定画面で選ばれた言語を保存する(例: "en", "ja-JP")
public static void Save(string cultureName)
{
Directory.CreateDirectory(Dir);
File.WriteAllText(FilePath, cultureName);
}
// 起動時、Application.Run(WPFならApplication起動)より前に呼ぶ。
// 保存が無い・壊れている場合は何もしない = OSの表示言語に従う
public static void ApplyOnStartup()
{
if (!File.Exists(FilePath)) return;
var name = File.ReadAllText(FilePath).Trim();
if (name.Length == 0) return;
try
{
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(name);
}
catch (CultureNotFoundException)
{
// 未知のカルチャ名。設定を無視してOSの表示言語のままにする
}
}
}
النقطة جعل حالة عدم وجود ملف الإعداد تعني «اتبع نظام التشغيل». عند التشغيل الأول أو عند تلف الملف لا يتوقف باستثناء، بل يسقط كما هو إلى القيمة الافتراضية لـ CurrentUICulture (الفصل 2).
6.2 الشكل الأدنى عند تنفيذ الخطة ب (السريان الفوري)
نستعرض هيكل التنفيذ احتياطاً إن لزم السريان الفوري بحكم المتطلب. في الحالين الشرط أن «كل الشاشات تركب هذه الآلية» لا يتغيّر.
إن استخدمت أسلوب المصمم في WinForms (Localizable = true)، أعد تطبيق resx حسب اللغة على النموذج المفتوح بـ ComponentResourceManager.
using System.ComponentModel;
using System.Globalization;
using System.Windows.Forms;
public partial class MainForm : Form
{
// 言語切り替え後、開いている各フォームで呼ぶ
public void ApplyCurrentLanguage(CultureInfo culture)
{
CultureInfo.DefaultThreadCurrentUICulture = culture;
CultureInfo.CurrentUICulture = culture; // 実行中のUIスレッドにも効かせる
var resources = new ComponentResourceManager(GetType());
// フォーム自身(タイトル・サイズ)は "$this" というキーで保存されている
resources.ApplyResources(this, "$this");
ApplyRecursive(Controls, resources);
}
private static void ApplyRecursive(
Control.ControlCollection controls, ComponentResourceManager resources)
{
foreach (Control control in controls)
{
resources.ApplyResources(control, control.Name);
ApplyRecursive(control.Controls, resources); // 入れ子のパネルも辿る
}
}
}
هذا التكرار لا يتتبع إلا Control، لذلك عناصر القوائم وأشرطة الأدوات (ToolStripItem ليس Control) تحتاج تتبّع ToolStrip.Items على حدة وتطبيق المعالجة نفسها. «القائمة وحدها لا تتغيّر لغتها» سببه هذا.
في WPF استبدل x:Static (صيغة تقرأ القيمة مرة) بربط، وألقِ إشعار تغيير عند تبديل اللغة.
using System.ComponentModel;
using System.Globalization;
using System.Windows.Data;
// 文字列の供給元。XAMLからはこのインスタンスにバインドする
public sealed class Loc : INotifyPropertyChanged
{
public static Loc Instance { get; } = new Loc();
private Loc() { }
// インデクサー経由でresxのキーを引く。見つからなければキー名をそのまま返す
public string this[string key] =>
Properties.Resources.ResourceManager.GetString(key, CultureInfo.CurrentUICulture) ?? key;
public event PropertyChangedEventHandler PropertyChanged;
public void ChangeLanguage(CultureInfo culture)
{
CultureInfo.DefaultThreadCurrentUICulture = culture;
CultureInfo.CurrentUICulture = culture;
// インデクサー全体の変更通知。Binding.IndexerName の中身は "Item[]"
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(Binding.IndexerName));
}
}
<!-- resxのアクセス修飾子はInternalまたはPublicにしておく -->
<Window xmlns:loc="clr-namespace:MyApp">
<Button Content="{Binding Path=[SaveButton], Source={x:Static loc:Loc.Instance}}" />
</Window>
الفرق عن المرجع المباشر بـ x:Static في الفصل 5 أنه ربط فيستطيع تلقّي إشعار التغيير فحسب. آلية resx وتجميعات الأقمار الصناعية في الخلف هي نفسها، لذلك عند الانتقال لاحقاً من الخطة أ إلى الخطة ب لا حاجة لإعادة صنع الموارد، والعمل يصير استبدال طريقة المرجع في XAML.
7. تعدد اللغات فيما وراء النصوص ── التخطيط والتنسيق والخطوط وRTL
حتى بعد انتهاء الترجمة، يبقى نصف تعدد اللغات.
- تمدد التخطيط. النص بالمعنى نفسه يختلف طوله كثيراً حسب اللغة («保存» اليابانية ← «Speichern» الألمانية). تخطيط الإحداثيات الثابتة والحجم الثابت ينهار عند كل ترجمة، لذلك في WinForms الطريقة الموجَّهة رسمياً الجمع بين
TableLayoutPanelوAutoSizeلتخطيط يتابع طول النص6. نظام تخطيط WPF متغيّر أصلاً، فيكفي تجنّب تثبيت العرض لمعظم الحالات. صمّم أيضاً مع إجراءات منع الانهيار في بيئة DPI العالية (دليل دعم DPI العالي في WinForms ودليل دعم DPI العالي في WPF) حتى لا يحدث رجوع. - تنسيق التاريخ والأرقام والعملة. عرض الشاشة اتركه لـ
CurrentCulture، وقلّل تثبيتToString("yyyy/MM/dd")الخاص من شيفرة الشاشة. وبالعكس ثبّت الملفات والسجلات وبيانات التكامل علىInvariantCulture(الفصل 2). - الخطوط. تحقق أن حروف اللغة المستهدفة موجودة في الخط. عند إضافة الصينية (المبسطة/التقليدية) أو الكورية، قد يصير شكل الحرف غير طبيعي إن بقي تحديد خط موجَّه لليابانية (مشكلة أشكال CJK). تجميع تحديد خط الواجهة في موضع واحد يسهّل التغيير عند إضافة لغة.
- اللغات التي تُكتب من اليمين إلى اليسار (RTL). في دعم العربية والعبرية يلزم، فوق ترجمة النص، عكس الشاشة يميناً ويساراً. WinForms يُضبط بخاصيتي
RightToLeft/RightToLeftLayout، وWPF بخاصيةFlowDirection. دعم RTL إن «أُضيف لاحقاً» صار مراجعة لكل الشاشات، فإن احتمل دخوله في اللغات المستهدفة فأدرجه في المتطلبات من البداية. - النص داخل الصور والأيقونات. النص المحروق في صورة لا يتبدل بآلية الموارد. تجنّب الصور ذات النص، واجعل التكوين صورة + تسمية نص، فهذا آمن.
حكم تصميم الواجهة عموماً أيضاً في جدول قرار تصميم UX لتطبيقات Windows.
8. التشغيل ── تسليم الترجمة وكشف النقص والتوزيع
أخيراً جانب التشغيل بعد قيام الآلية.
- أرفق السياق عند تسليم الترجمة. تسليم مفتاح resx والنص الأصلي وحدهما لا يثبّت جودة ترجمة نصوص قصيرة مثل «OK» و«開く». التعامل الواقعي جدول مقابلة (جدول بيانات وغيره) يضيف إلى المفتاح والأصل والترجمة «الشاشة المعروضة والاستخدام»، ثم عكسه إلى resx بعد الاستلام.
- اكتشف نقص الترجمة بالرجوع الاحتياطي. بنتيجة الرجوع الاحتياطي للموارد يظهر نقص الترجمة بشكل «اختلاط اللغة الافتراضية في شاشة تلك اللغة»2. ضع في CI تحققاً بسيطاً (سكريبت أو شيفرة اختبار) يقابل قائمة مفاتيح resx حسب اللغة مع resx المحايد، فيُكشف آلياً قبل الإصدار.
- ضمّن تجميعات الأقمار الصناعية في التوزيع. إن لم تُوزَّع مجلدات اللغة مثل
ja/وen/كما هي، رجعت تلك اللغة وحدها احتياطياً وصارت حالة «ترجمنا لكن لا يسري». تسرّب مجلد اللغة عند النسخ اليدوي حادث نمطي، فأدرج بنية المجلدات كما هي في المثبّت (MSI/MSIX وغيرها). في توزيع ClickOnce تُدرج تجميعات الأقمار الصناعية لكل اللغات في النشر افتراضياً7. حكم طريقة التوزيع كلها في كيفية اختيار طريقة توزيع تطبيقات Windows.
الخلاصة
تعدد اللغات في تطبيقات سطح المكتب يقوم على آلية ناضجة هي resx وتجميعات الأقمار الصناعية، والآلية نفسها ليست صعبة. ما يفصل النجاح في العمل هو تصميم يميّز CurrentCulture عن CurrentUICulture، وانضباط بعدم كتابة النص المعروض للمستخدم مباشرة، وتخطيط يحتمل طول النص بعد الترجمة، وتمييز المتطلب «هل التبديل الفوري لازم حقاً». في WPF لا تنجرف وراء معلومات أسلوب LocBaml القديم، والحل العملي الحالي البناء على أساس resx.
اختيار الطريقة وتقدير نطاق التأثير عند إضافة تعدد اللغات لاحقاً إلى تطبيق قائم، ودعم تعدد اللغات للشاشات والتقارير وبيانات التكامل تمهيداً للنشر في فروع خارجية، كثيراً ما تحتاج حكماً مع النظر في حالة قاعدة الشيفرة، فإن ترددت فاستشرنا.
مقالات ذات صلة
- جدول قرار التمييز بين WinForms / WPF / WinUI
- جدول قرار تصميم UX لتطبيقات Windows
- تصميم التاريخ والوقت والمنطقة الزمنية في تطبيقات الأعمال
- دليل دعم DPI العالي في WinForms
- دليل دعم DPI العالي في WPF
- ليس appsettings.json وحده ── الممارسة العملية لإدارة الإعداد في تطبيقات Windows للأعمال
- كيفية اختيار طريقة توزيع تطبيقات Windows (MSI / MSIX / ClickOnce / xcopy / محدّث ذاتي)
- آلية ملف تعريف مستخدم Windows
مجالات الاستشارة ذات الصلة
تتعامل شركة كومورا سوفت ذ.م.م. مع تصميم تعدد اللغات في تطبيقات WinForms/WPF وتنفيذه، ومع الاستشارة التقنية لاختيار الطريقة وترتيب نطاق التأثير عند إضافة تعدد اللغات لاحقاً إلى تطبيق قائم.
المراجع
-
Microsoft Learn، WPF Globalization and Localization Overview. حول توليد تجميعة قمر صناعي بضبط
UICultureفي ملف المشروع، ودورxml:langعلى عنصر الجذر، وأن LocBaml أداة عيّنة خاصة بـ WPF على .NET Framework ولا تعمل في WPF على .NET. ↩ ↩2 ↩3 ↩4 ↩5 -
Microsoft Learn، Retrieve resources in .NET apps. حول عملية الرجوع الاحتياطي للموارد (البحث بالترتيب ثقافة محددة ← ثقافة محايدة ← موارد الافتراضي في التجميعة الرئيسة). ↩ ↩2 ↩3
-
Microsoft Learn، CultureInfo.CurrentUICulture Property. حول أن
CurrentUICultureيُستخدم في بحث مدير الموارد عن الموارد الخاصة بالثقافة، وأن القيمة الافتراضية تأتي من لغة واجهة المستخدم في نظام التشغيل، وضبط القيمة الافتراضية لكل الخيوط بـDefaultThreadCurrentUICulture. ↩ ↩2 -
Microsoft Learn، Resources in .NET apps. حول إنشاء موارد resx وتعبئتها، ونموذج المحور والأشعة بتجميعة رئيسة وتجميعات أقمار صناعية، وسمة
NeutralResourcesLanguage. ↩ ↩2 -
Microsoft Learn، Walkthrough: Localizing a Hybrid Application. حول إجراء توليد resx حسب اللغة (مثال: Form1.es-ES.resx) بجعل خاصية
Localizableتساويtrueفي مصمم نماذج Windows وتبديل خاصيةLanguage، ومثال ضبطCurrentUICultureقبل استدعاءInitializeComponent. ↩ -
Microsoft Learn، How to: Design a Windows Forms Layout that Responds Well to Localization. حول صنع تخطيط يتابع فيه حجم عنصر التحكم تغيّر طول نص خاصية
Textبسبب التوطين باستخدامTableLayoutPanel. ↩ -
Microsoft Learn، Localize ClickOnce applications. حول أن أسلوب إدراج كل تجميعات الأقمار الصناعية في نشر واحد هو افتراضي Visual Studio، وأن تجميعة القمر الصناعي الموافقة لثقافة نظام التشغيل تُستخدم عند التشغيل. ↩
مقالات ذات صلة
أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.
انتهاء خدمة برامج تشغيل الطابعات في Windows ── كيف تستعد تطبيقات الأعمال لطباعة التقارير والملصقات
تُنهى Microsoft تدريجيّاً خدمة برامج تشغيل الطابعات v3/v4، ومن تمّوز/يوليو 2026 يُفضَّل برنامج تشغيل فئة IPP. نرتّب في جداول قرار ما يختف...
الطباعة وإخراج PDF في تطبيقات أعمال Windows ── التمييز بين System.Drawing.Printing وWPF ومكتبات التقارير
نرتّب بجدول قرار حسب المتطلبات طباعة WinForms عبر PrintDocument، وطباعة FlowDocument/FixedDocument في WPF، وخيارات إخراج PDF. ونشرح التحك...
ما ينبغي تنظيمه قبل طلب التعهيد أو التطوير التعاقديّ لتطبيق Windows
قبل تكليف جهة خارجية بتطوير تطبيق Windows تعاقديّاً، إليك النقاط التي ينبغي تنظيمها: تعديل البرمجيّات القائمة، وتكامل الأجهزة، وCOM/Activ...
CI/CD عمليّ لتطبيقات WinForms / WPF ── أتمتة البناء والتوقيع والتوزيع عبر GitHub Actions
دليل عمليّ لبناء CI/CD لتطبيقات WinForms / WPF عبر GitHub Actions. يشمل YAML الأدنى للبناء والاختبار على windows-latest، وترقيم الإصدار ا...
إقامة تطبيقات Windows في علبة النظام والإشعارات المنبثقة ── مطبات NotifyIcon وكيفية اختيار AppNotification
نرتّب إقامة تطبيقات Windows للأعمال في علبة النظام والإشعارات المنبثقة. نشرح الاستخدام الصحيح لـ NotifyIcon، وإعادة التسجيل عند إعادة تشغ...
أين يتصل هذا الموضوع
ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.
تطوير تطبيقات ويندوز
لأن تصميم وتنفيذ دعم تعدد اللغات في تطبيقات سطح المكتب يقع ضمن نطاق الاستشارات العملية لتطوير تطبيقات Windows.
الاستشارات التقنية ومراجعة التصميم
لأن اختيار الطريقة المناسبة وتقدير نطاق التأثير عند إضافة دعم تعدد اللغات لاحقًا إلى تطبيق قائم يندرج ضمن الاستشارة التقنية التي تتضمن مراجعة التصميم.
الأسئلة الشائعة
أسئلة شائعة حول موضوع هذه المقالة.
- هل يمكن إضافة دعم تعدد اللغات لاحقاً إلى تطبيق قائم صُنع باليابانية وحدها؟
- نعم يمكن، لكن معظم العمل ليس «إدخال آلية الموارد» بل «حصر النصوص المكتوبة مباشرة في الشيفرة واستبدالها». يلزم جرد ليس نصوص الشاشات فقط، بل أيضاً مربعات الرسائل والسجلات ورسائل الاستثناء والتقارير وحتى النصوص المعروضة المخزَّنة في قاعدة البيانات، والحجم يتحدد بتشتت النصوص أكثر من عدد الشاشات. إن حرصت من مرحلة التطوير الجديد على تمرير النصوص التي تُعرض للمستخدم عبر resx فقط، انخفضت تكلفة تعدد اللغات مستقبلاً بدرجة كبيرة جداً.
- هل يجوز الاكتفاء بالترجمة الآلية؟
- للأدوات الداخلية أو الحلول المؤقتة البدء بالترجمة الآلية أمر واقعي. لكن تطبيقات الأعمال تكثر فيها الكلمات القصيرة في الأزرار والقوائم (مثل «登録» أو «取消»)، وهذا مجال ترتفع فيه نسبة خطأ الترجمة الآلية عند غياب السياق. يُنصح كحد أدنى بجولة مراجعة واحدة يجرب فيها متحدث فعلي بتلك اللغة الشاشات. كذلك، الأهم قبل جودة الترجمة نفسها ضمان «عدم انهيار التخطيط عند طول النص بعد الترجمة»، عبر TableLayoutPanel وAutoSize مسبقاً.
- هل يجب ترجمة السجلات ورسائل الأخطاء أيضاً؟
- القاعدة الثابتة في العمل ترجمة الرسائل التي تظهر على شاشة المستخدم، وعدم ترجمة المحتوى المكتوب في ملفات السجلات أو سجل الأحداث (أي تثبيت لغة واحدة). السجلات يقرأها المطوّرون والقائمون على التشغيل لا المستخدمون، والسجلات متعددة اللغات تُفسد إمكانية البحث عند التحقيق. كذلك ثبّت تنسيق السجلات (التاريخ والأرقام) على CultureInfo.InvariantCulture. إن صممت التعامل مع CurrentCulture وCurrentUICulture منفصلين، تحقق هذا الفصل بين الاستخدامين طبيعياً.
- هل ينبغي جعل التطبيق قادراً على تبديل اللغة بمعزل عن لغة عرض نظام التشغيل؟
- عند النشر في فروع خارج اليابان، أو تطبيقات الأعمال التي يستخدمها موظفون ناطقون بلغات أجنبية داخل اليابان، تكون قيمة إعداد لغة خاص بالتطبيق عالية. الأسلوب الآمن نهجان: اتباع لغة عرض نظام التشغيل افتراضياً (القيمة الافتراضية لـ CurrentUICulture)، والكتابة فوقها فقط عند اختيار المستخدم الصريح لها من شاشة الإعدادات. وجعل تطبيق التبديل يتم «عند إعادة التشغيل التالية» كمواصفة هو الخيار الأكثر أماناً، إذ يبسّط التنفيذ وشرح طريقة الاستخدام.
الملف الشخصي للمؤلف
صفحة الملف الشخصي لمؤلف المقالة.
غو كومورا
مؤسّس شركة كومورا سوفت ذ.م.م.
يركّز على تطوير برامج ويندوز، والاستشارات التقنية، والتحقيق في الأخطاء، ويتميّز في المشاريع التي تبقى فيها الأصول القديمة ناشطة، وفي تشخيص الأعطال التي يصعب تحديد سببها.