تعدد اللغات في تطبيقات WinForms/WPF ── الممارسة العملية لملفات resx وتجميعات الأقمار الصناعية (Satellite Assemblies) وتبديل الثقافة (Culture)

· · CSharp, .NET, WinForms, WPF, تعدد اللغات, التوطين, الموارد, UI, تطوير Windows, الاستشارة التقنية

«نريد استخدام نفس التطبيق في الفروع الخارجية أيضًا»، «ازداد عدد الموظفين الناطقين بلغات أجنبية في موقع المصنع، لذا نريد أن تكون الشاشات بالإنجليزية أيضًا» ── يبدو تعدد اللغات في تطبيقات سطح المكتب على Windows مطلبًا بسيطًا، لكن بمجرد الشروع فيه تتوالى نقاط الحيرة: «كيف نستخدم resx؟»، «توجد عدة طرق في WPF ولا نعرف أيها الصحيح»، «هل يمكن تبديل اللغة أثناء التشغيل؟».

في هذا المقال، وبافتراض تطبيقات مؤسسية مبنية بـ WinForms/WPF، سنستعرض بترتيب نقاط الحيرة الفعلية في الممارسة العملية: أساسيات التوطين في .NET (الثقافة (Culture) والرجوع الاحتياطي للموارد Resource Fallback)، وآلية عمل resx وتجميعات الأقمار الصناعية (Satellite Assemblies)، والطرق الواقعية حسب كل إطار عمل، وتبديل اللغة أثناء التشغيل، ووصولًا إلى نقاط ما وراء النصوص (التنسيق والتخطيط ودعم RTL).

1. الخلاصة أولًا (جدول القرار)

تتحدد طريقة تعدد اللغات وفق التوليفة بين إطار العمل والمتطلبات.

الحالة الطريقة الموصى بها السبب
WinForms - الشاشات التي تتمحور حول التسميات (Labels) والأزرار تفعيل Localizable = true في النموذج (Form) + ملفات resx خاصة بكل لغة (أسلوب المصمم Designer) يمكن ضبط نصوص عناصر التحكم وحجمها وموضعها حسب كل لغة، ويتم إنجاز كل ذلك داخل Visual Studio فقط
مشترك بين WinForms وWPF - عندما تكثر الرسائل والنصوص المشتركة ملف resx مشترك (Resources.resx + Resources.ja.resx وما شابه) + الفئة (Class) ذات النوع المُولّدة تلقائيًا يمكن الرجوع إلى النصوص من الكود بأمان من ناحية الأنواع (Type-safe)، ويمكن مشاركة نفس النصوص بين الشاشة والمنطق البرمجي
WPF resx مشترك + ربط (Binding) عبر x:Static لا يمكن استخدام أسلوب LocBaml في WPF على .NET (Core)1. أما أسلوب resx فيتيح مشاركة المعرفة مع WinForms
عندما يكون تبديل اللغة أثناء التشغيل ضروريًا resx + آلية إشعار التغيير (أو إعادة إنشاء الشاشة) تحقق أولًا، قبل اختيار الطريقة، من كون «التبديل دون إعادة التشغيل ضروريًا فعلًا» كمتطلب (الفصل 6)
عند تكليف جهة خارجية بالترجمة التصميم بالاعتماد على resx، والتسليم عبر جدول مطابقة بين المفاتيح (Keys) والنصوص المترجمة بما أن resx بصيغة XML يمكن تسليمه كما هو، إلا أن إرفاق معلومات السياق (أي شاشة وأي زر) هو ما يحدد جودة النتيجة فعليًا

نذكر الخلاصة أولًا فيما يلي.

  • CurrentCulture (التنسيق) وCurrentUICulture (لغة الموارد) شيئان مختلفان تمامًا. هذا التمييز هو الأساس الذي يقوم عليه تصميم تعدد اللغات بأكمله (الفصل 2).
  • جوهر الموارد هو «موارد اللغة المحايدة + تجميعات أقمار صناعية (Satellite Assemblies) خاصة بكل لغة»، والرجوع الاحتياطي (Fallback) يتم تلقائيًا. يتم البحث بالترتيب ja-JPja ← اللغة المحايدة، لذا حتى في حال نقص إحدى الترجمات لا يتعطل التطبيق بل يُعرض بلغته الافتراضية2.
  • الحل العملي في WinForms هو الجمع بين أسلوب المصمم (Localizable = true) وأسلوب resx المشترك. تُعالج الشاشات بأسلوب المصمم، بينما تُوجَّه رسائل صناديق الحوار والنصوص المشتركة إلى resx المشترك (الفصل 4).
  • أسلوب LocBaml الوارد في الدليل الرسمي لـ WPF لا يمكن استخدامه في .NET (Core)1. الخيار الأول في الممارسة الحالية هو أسلوب resx مع x:Static (أو الربط Binding) (الفصل 5).
  • اجعل خيارك الأول لتبديل اللغة أثناء التشغيل هو «التطبيق عند إعادة التشغيل التالية». ذلك لأن موارد الشاشة المعروضة حاليًا لا تُستبدل تلقائيًا (الفصل 6).
  • ترجمة النصوص ليست سوى نصف عملية تعدد اللغات. أما النصف الآخر فيشمل تكيّف التخطيط مع طول النص بعد الترجمة، وتنسيق التاريخ والأرقام، والخطوط، ودعم اللغات التي تُكتب من اليمين إلى اليسار (RTL) (الفصل 7).

2. الأساس ── الفرق بين CurrentCulture وCurrentUICulture

يحتوي إعداد الثقافة (Culture) في .NET على خاصيتين (Properties) بأدوار مختلفة3.

الخاصية (Property) ما تحدده مثال
CultureInfo.CurrentCulture تنسيق التاريخ والأرقام والعملة عرض 2026/07/07 أو 7/7/2026
CultureInfo.CurrentUICulture تحديد موارد أي لغة يتم تحميلها عرض «保存» على الزر أو عرض «Save»

يمكن ضبط هاتين الخاصيتين بشكل مستقل عن بعضهما. فمثلًا توليفة «الشاشة بالإنجليزية، لكن التاريخ والعملة بالتنسيق الياباني» (وهو متطلب شائع في التطبيقات المؤسسية الموجهة للناطقين بلغات أجنبية داخل اليابان) يمكن تمثيلها بشكل طبيعي عبر CurrentUICulture = en مع CurrentCulture = ja-JP.

القيمتان الافتراضيتان لكلتيهما مستمدتان من إعدادات نظام التشغيل، لذا فإن نقطة الانطلاق هي «إذا لم تفعل شيئًا، يتبع التطبيق نظام التشغيل». وعند الرغبة في تبديل اللغة صراحةً على مستوى التطبيق بأكمله، فالأفضل استبدال القيم الافتراضية نفسها بدلًا من الضبط على مستوى كل خيط (Thread) على حدة.

using System.Globalization;

// استبدال الثقافة الافتراضية لجميع الخيوط (Threads) التي تُنشأ بعد هذه النقطة
// (يُنفَّذ قبل إنشاء خيط واجهة المستخدم = قبل 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 وتجميعات الأقمار الصناعية والرجوع الاحتياطي (Fallback)

يعتمد التوطين في .NET على نموذج «المحور والأطراف» (Hub and Spoke). حيث تُدمج موارد اللغة الافتراضية (المحايدة) في التجميع (Assembly) الرئيسي، بينما تُفصل موارد كل لغة إلى ملف DLL منفصل يُسمى تجميع الأقمار الصناعية (Satellite Assembly)4.

عند البناء (Build)، تكون بنية الإخراج لملفات resx الخاصة بكل لغة على النحو التالي.

MyApp.exe                     ← الملف الرئيسي (يتضمن الموارد المحايدة)
MyApp.dll
ja/MyApp.resources.dll        ← تجميع الأقمار الصناعية للغة اليابانية
en/MyApp.resources.dll        ← تجميع الأقمار الصناعية للغة الإنجليزية

عند التشغيل، يبحث مدير الموارد (Resource Manager) عن الموارد بدءًا من CurrentUICulture وبالترتيب التالي: الثقافة المحددة (ja-JP) ← الثقافة المحايدة (ja) ← الموارد الافتراضية (الملف الرئيسي)2. وبفضل هذا الرجوع الاحتياطي التلقائي، حتى في حال غياب ترجمة واحدة، لا يتعطل التطبيق بل تُعرض النصوص باللغة الافتراضية. وبعبارة أخرى، ظهور بعض النصوص اليابانية وسط شاشة يُفترض أن تكون بالإنجليزية بالكامل هو علامة على نقص في الترجمة، ويمكن الاستفادة من ذلك كنقطة اختبار (الفصل 8).

في الممارسة العملية، ينبغي مراعاة النقطتين التاليتين.

  • الإعلان عن الثقافة التي تمثل اللغة الافتراضية عبر السمة (Attribute) NeutralResourcesLanguage يُلغي البحث غير الضروري عن تجميع الأقمار الصناعية عند استخدام الثقافة الافتراضية، ويجعل نقطة نهاية الرجوع الاحتياطي واضحة4.
  • بما أن تجميعات الأقمار الصناعية «لا تعمل إلا إذا وُزِّعت مع الملف الرئيسي»، يجب تضمين مجلدات اللغات في تصميم برنامج التثبيت أو النسخ المباشر عند التوزيع (الفصل 8).

4. الممارسة العملية في WinForms ── أسلوب المصمم وأسلوب resx المشترك

يوجد في WinForms أسلوبان، ويُستخدمان معًا في الممارسة العملية.

4.1 الشاشات بأسلوب المصمم (Localizable = true)

عند ضبط الخاصية Localizable على true في خصائص النموذج (Form)، ثم تبديل خاصية Language إلى اللغة المستهدفة (الإنجليزية مثلًا) قبل تعديل خاصية Text للتسميات والأزرار، يقوم Visual Studio تلقائيًا بإنشاء ملف resx خاص باللغة مثل Form1.en.resx5.

تكمن قوة هذا الأسلوب في أنه لا يحفظ النصوص فقط، بل يحفظ أيضًا حجم عناصر التحكم وموضعها لكل لغة على حدة. فيمكن أن تعالج داخل المصمم مشكلة مثل تحول كلمة «登録» اليابانية إلى «Register» بالإنجليزية وتجاوزها لحدود الزر، وضبطها لكل لغة على حدة. لكن في المقابل، يزداد عدد ملفات resx بمقدار عدد اللغات مضروبًا في عدد النماذج، وتنشأ تكلفة صيانة تتمثل في ضرورة التحقق من جميع اللغات في كل مرة يتغير فيها تخطيط النموذج. فإذا كان من المتوقع أن يزداد عدد اللغات، فامنح الأولوية لبناء شاشات «لا تنهار دون الحاجة إلى تعديل» باستخدام الإجراءات الخاصة بالتخطيط الواردة لاحقًا (الفصل 7).

4.2 الرسائل والنصوص المشتركة بأسلوب resx المشترك

أما النصوص المستخدمة من الكود، مثل نصوص صناديق الحوار (MessageBox) ومربعات التأكيد وعرض شريط الحالة، فتُجمَع في ملف Resources.resx مشترك على مستوى المشروع، وتُضاف ملفات خاصة بكل لغة مثل Resources.en.resx. وبما أن resx يُنشئ تلقائيًا فئة (Class) ذات نوع محدد (Typed Class)، فيمكن الرجوع إليها من الكود دون احتمال الخطأ في كتابة المفتاح (Key).

// الرجوع عبر الفئة ذات النوع المحدد (Typed Class) المُولّدة تلقائيًا.
// النص المُرجَع يتبدل تلقائيًا حسب CurrentUICulture
MessageBox.Show(
    Properties.Resources.ConfirmDeleteMessage,
    Properties.Resources.ConfirmTitle,
    MessageBoxButtons.YesNo);

أهم قاعدة هنا هي عدم كتابة النصوص التي تُعرض للمستخدم مباشرة داخل الكود. فجهد تعدد اللغات لا يُصرف على إدخال الآلية نفسها، بل على «تجميع النصوص المكتوبة مباشرة والمتناثرة في أنحاء الكود». وهذه هي القيمة الحقيقية لتمرير النصوص عبر resx حتى في مرحلة التشغيل بلغة واحدة فقط.

5. الممارسة العملية في WPF ── اجعل resx خيارك الأول بدلًا من LocBaml

يُعد تعدد اللغات في WPF مجالًا يسهل فيه اختلاط المعلومات. يتضمن الدليل الرسمي (Walkthrough) أسلوبًا يعتمد على ضبط UICulture في ملف المشروع لتوليد موارد BAML، ثم إدخال الترجمة عبر أداة LocBaml، لكن LocBaml هي أداة عينة (Sample Tool) مخصصة حصريًا لـ WPF على .NET Framework، ولا تعمل مع WPF على .NET (Core)1. لذا اعتبر أنه ليس أسلوبًا يُختار حديثًا في الوقت الحالي.

الخيار الأول عمليًا هو الرجوع من XAML إلى نفس أسلوب resx المشترك المستخدم في WinForms.

<!-- بعد ضبط معدّل الوصول (Access Modifier) لملف 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، مما يتيح إدارة النصوص بشكل موحد حتى في الحلول (Solutions) المختلطة. وبما أن x:Static هو مرجع ثابت (Static Reference) يُحل عند بدء التشغيل، فإذا كان تبديل اللغة أثناء التشغيل مطلوبًا، يمكن تطويره إلى ربط (Binding) مع آلية إشعار بالتغيير (الفصل 6).

كما أن ضبط خاصية xml:lang للعنصر الجذر (Root Element) في XAML يضمن عمل ميزات WPF المعتمدة على اللغة بشكل صحيح، مثل الفصل المقطعي للكلمات (Hyphenation) والرجوع الاحتياطي للخطوط (Font Fallback) وعرض الأرقام1.

للاطلاع على كيفية اتخاذ القرار بشأن استخدام WinForms أو WPF أصلًا، راجع مقال «جدول اختيار WinForms / WPF / WinUI».

6. تبديل اللغة أثناء التشغيل ── اجعل «التطبيق عند إعادة التشغيل التالية» خيارك الأول

عندما يكون المتطلب هو السماح للمستخدم باختيار اللغة من شاشة الإعدادات، يوجد خياران لتوقيت التطبيق.

  • الخيار أ: التطبيق عند إعادة التشغيل التالية (موصى به). يُحفظ اللغة المختارة في ملف الإعدادات، ويُضبط DefaultThreadCurrentUICulture قبل Application.Run عند بدء التشغيل (أو قبل بدء Application في حالة WPF). التنفيذ بسيط، ولا تحدث بنيويًا الأعطال المصاحبة لإعادة بناء الشاشة (مثل فقدان البيانات أثناء الإدخال أو التسجيل المزدوج لمعالجات الأحداث Event Handlers).
  • الخيار ب: التطبيق الفوري. حتى مع تغيير CurrentUICulture، لا تُستبدل نصوص الشاشة المعروضة بالفعل تلقائيًا. ففي حالة أسلوب المصمم في WinForms، يجب إعادة تطبيق الموارد على النماذج المفتوحة عبر ComponentResourceManager.ApplyResources، وفي حالة WPF يجب تزويد النصوص عبر الربط (Binding) مع آلية إشعار بالتغيير. وفي الحالتين، يصبح الافتراض المسبق لهذا البناء هو «أن جميع الشاشات تدعم إعادة تطبيق الموارد».

في التطبيقات المؤسسية، غالبًا ما لا تتناسب تكلفة تنفيذ واختبار الخيار ب مع تكرار تغيير اللغة (عادة مرة واحدة عند الإدخال)، لذا نوصي باعتماد الخيار أ كافتراضي، والاقتصار على الخيار ب فقط عندما يكون ضروريًا فعلًا كمتطلب. أما مكان حفظ إعداد اللغة، فبما أنه إعداد خاص بكل مستخدم، فإن المكان المناسب هو داخل %LOCALAPPDATA%. للاطلاع على كيفية تحديد مكان حفظ الإعدادات، راجع جدول القرار في مقال «الممارسة العملية لإدارة الإعدادات في تطبيقات Windows المؤسسية».

7. تعدد اللغات فيما وراء النصوص ── التخطيط والتنسيق والخطوط ودعم RTL

حتى بعد الانتهاء من الترجمة، يبقى نصف عملية تعدد اللغات دون إنجاز.

  • مرونة التخطيط. حتى النصوص التي تحمل المعنى نفسه يختلف طولها اختلافًا كبيرًا بين اللغات (اليابانية «保存» ← الألمانية «Speichern»). والتخطيطات ذات الإحداثيات والأحجام الثابتة تنهار مع كل ترجمة، لذا فإن الطريقة الموصى بها رسميًا في WinForms هي الجمع بين TableLayoutPanel وAutoSize لبناء تخطيط يتكيف مع طول النص6. أما في WPF فنظام التخطيط مرن أصلًا، ويكفي تجنب تحديد العرض بشكل ثابت لتغطية معظم الحالات. كما يُفضَّل تصميم ذلك بالتزامن مع معالجة مشكلات الانهيار في بيئات الدقة العالية (High DPI) (راجع «دليل التعامل مع الدقة العالية (High DPI) في WinForms» و«دليل التعامل مع الدقة العالية (High DPI) في WPF») لتفادي إعادة العمل لاحقًا.
  • تنسيق التاريخ والأرقام والعملة. اترك عرض الشاشة لـ CurrentCulture، وقلّل من استخدام تنسيق ثابت مثل ToString("yyyy/MM/dd") مباشرة في كود الشاشة. وفي المقابل، ثبّت تنسيق الملفات والسجلات وبيانات التكامل على InvariantCulture (الفصل 2).
  • الخطوط. تحقق من أن الخط يحتوي على حروف اللغة المستهدفة. عند إضافة الصينية (المبسطة/التقليدية) أو الكورية، قد تبدو أشكال الحروف غير طبيعية إذا بقي تحديد الخط مخصصًا لليابانية (ما يُعرف بمشكلة أشكال حروف CJK). تجميع تحديد خط واجهة المستخدم في مكان واحد يُسهّل التعديل عند إضافة لغات جديدة.
  • اللغات التي تُكتب من اليمين إلى اليسار (RTL). عند دعم العربية أو العبرية، يلزم بالإضافة إلى ترجمة النصوص عكس اتجاه الشاشة أفقيًا. يتم التحكم في ذلك في WinForms عبر خاصيتي RightToLeft / RightToLeftLayout، وفي WPF عبر خاصية FlowDirection. وبما أن إضافة دعم RTL «لاحقًا» تعني إعادة النظر في جميع الشاشات، فإذا كان هناك احتمال لإضافة لغة من هذا النوع مستقبلًا، فأدرج ذلك ضمن المتطلبات منذ البداية.
  • النصوص داخل الصور والأيقونات. النصوص المدمجة داخل الصور لا تتبدل عبر آلية الموارد. الأسلوب الآمن هو تجنب الصور التي تحتوي على نصوص، واعتماد بنية تجمع بين الصورة وتسمية نصية (Text Label) منفصلة.

للاطلاع على القرارات الشاملة لتصميم واجهة المستخدم، راجع أيضًا مقال «جدول قرار تصميم تجربة المستخدم (UX) لتطبيقات Windows».

8. التشغيل ── تسليم الترجمة واكتشاف النواقص والتوزيع

أخيرًا، نتناول جانب التشغيل بعد اكتمال بناء الآلية.

  • أرفق السياق عند تسليم الترجمة. تسليم مفتاح resx والنص الأصلي فقط لا يضمن جودة ثابتة لترجمة النصوص القصيرة مثل «OK» أو «فتح». الأسلوب الواقعي هو التواصل عبر جدول مطابقة (مثل جدول بيانات) يتضمن المفتاح والنص الأصلي والترجمة مع إرفاق «الشاشة التي يظهر فيها النص والغرض منه»، ثم تطبيقه على resx بعد الاستلام.
  • اكتشف النواقص في الترجمة عبر آلية الرجوع الاحتياطي. بفضل الرجوع الاحتياطي للموارد، تظهر النواقص في الترجمة على شكل «اختلاط اللغة الافتراضية بشاشة تلك اللغة»2. إدراج فحص بسيط (عبر سكربت أو كود اختبار) في CI يقارن قائمة مفاتيح ملف resx الخاص بكل لغة مع ملف resx المحايد يتيح اكتشاف ذلك آليًا قبل الإصدار.
  • ضمّن تجميعات الأقمار الصناعية في التوزيع. ما لم تُوزَّع مجلدات اللغات مثل ja/ وen/ بالكامل، ستقع تلك اللغة تحديدًا في حالة رجوع احتياطي، فتظهر حالة «تمت الترجمة لكنها لا تُطبَّق». وبما أن نسيان مجلد لغة عند النسخ اليدوي خطأ شائع كلاسيكي، فادرج بنية المجلدات بالكامل في برنامج التثبيت (MSI/MSIX وغيرها). أما في توزيع ClickOnce، فتُدرج تجميعات الأقمار الصناعية لجميع اللغات افتراضيًا في عملية النشر7. للاطلاع على القرار الشامل لطريقة التوزيع، راجع مقال «كيفية اختيار طريقة توزيع تطبيقات Windows».

الخلاصة

يقوم تعدد اللغات في تطبيقات سطح المكتب على آلية ناضجة ومُختبرة تتمثل في resx وتجميعات الأقمار الصناعية، والآلية نفسها ليست صعبة. أما ما يحدد نجاح التنفيذ عمليًا من فشله فهو: التصميم الذي يميّز بين CurrentCulture وCurrentUICulture، والانضباط في عدم كتابة النصوص التي تُعرض للمستخدم مباشرة داخل الكود، والتخطيط القادر على استيعاب طول النص بعد الترجمة، وتقييم متطلب «هل التبديل الفوري ضروري فعلًا؟». وفي WPF، الحل العملي الحالي هو البناء اعتمادًا على resx دون الانجرار وراء المعلومات القديمة الخاصة بأسلوب LocBaml.

غالبًا ما يتطلب اختيار طريقة تعدد اللغات وتقدير نطاق تأثيرها في التطبيقات القائمة، وكذلك دعم تعدد اللغات في الشاشات والتقارير وبيانات التكامل استعدادًا للتوسع في فروع خارجية، اتخاذ قرارات بناءً على الوضع الفعلي لقاعدة الكود. فإذا تردّدتم، لا تترددوا في التواصل معنا للاستشارة.

مقالات ذات صلة

مجالات الاستشارة ذات الصلة

تقدّم شركة كومورا سوفت ذات المسؤولية المحدودة استشارات تقنية بشأن تصميم وتنفيذ دعم تعدد اللغات في تطبيقات WinForms/WPF، واختيار الطريقة المناسبة وتحديد نطاق التأثير عند إضافة دعم تعدد اللغات لاحقًا إلى تطبيق قائم.

المراجع

  1. Microsoft Learn، WPF Globalization and Localization Overview. حول توليد تجميعات الأقمار الصناعية عبر ضبط UICulture في ملف المشروع، ودور xml:lang في العنصر الجذر، وكون LocBaml أداة عينة مخصصة حصريًا لـ WPF على .NET Framework ولا تعمل مع WPF على .NET.  2 3 4

  2. Microsoft Learn، Retrieve resources in .NET apps. حول عملية الرجوع الاحتياطي للموارد (البحث بالترتيب: الثقافة المحددة ← الثقافة المحايدة ← الموارد الافتراضية في التجميع الرئيسي).  2 3

  3. Microsoft Learn، CultureInfo.CurrentUICulture Property. حول استخدام CurrentUICulture من قِبل مدير الموارد (Resource Manager) للبحث عن الموارد الخاصة بثقافة معينة، وكون القيمة الافتراضية مستمدة من لغة واجهة مستخدم نظام التشغيل، وضبط القيمة الافتراضية لجميع الخيوط عبر DefaultThreadCurrentUICulture 2

  4. Microsoft Learn، Resources in .NET apps. حول إنشاء موارد resx وتحزيمها، ونموذج «المحور والأطراف» (Hub and Spoke) عبر التجميع الرئيسي وتجميعات الأقمار الصناعية، والسمة (Attribute) NeutralResourcesLanguage 2

  5. Microsoft Learn، Walkthrough: Localizing a Hybrid Application. حول خطوات ضبط الخاصية Localizable على true وتبديل خاصية Language في مصمم نماذج Windows (Windows Forms Designer) لإنشاء ملف resx خاص باللغة (مثل Form1.es-ES.resx)، ومثال على ضبط CurrentUICulture قبل استدعاء InitializeComponent

  6. Microsoft Learn، How to: Design a Windows Forms Layout that Responds Well to Localization. حول طريقة استخدام TableLayoutPanel لبناء تخطيط يتكيف حجم عناصر التحكم فيه مع تغير طول النص في الخاصية Text بسبب التوطين. 

  7. Microsoft Learn، Localize ClickOnce applications. حول كون تضمين جميع تجميعات الأقمار الصناعية في عملية نشر واحدة هو الإعداد الافتراضي في Visual Studio، واستخدام تجميع الأقمار الصناعية المطابق لثقافة نظام التشغيل عند التشغيل. 

أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.

ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.

الأسئلة الشائعة

أسئلة شائعة حول موضوع هذه المقالة.

هل يمكن إضافة دعم تعدد اللغات لاحقًا إلى تطبيق قائم تم إنشاؤه باللغة اليابانية فقط؟
نعم، يمكن ذلك، لكن معظم العمل لا يتمثل في «إدخال آلية الموارد» بل في «حصر واستبدال النصوص المكتوبة مباشرة داخل الكود». يجب حصر ليس فقط نصوص الشاشات، بل أيضًا رسائل صناديق الحوار (MessageBox) والسجلات (Logs) ورسائل الاستثناءات والتقارير وحتى النصوص المعروضة المخزّنة في قاعدة البيانات، وحجم العمل يتحدد بمدى تشتت هذه النصوص أكثر من عدد الشاشات نفسها. إذا حرصت منذ مرحلة التطوير الجديد على تمرير النصوص التي تُعرض للمستخدم عبر resx فقط، فإن تكلفة تعدد اللغات في المستقبل تنخفض بشكل كبير جدًا.
هل يجوز الاكتفاء بالترجمة الآلية؟
بالنسبة للأدوات الداخلية أو الحلول المؤقتة، فإن البدء بالترجمة الآلية أمر واقعي. لكن التطبيقات المؤسسية تحتوي على كلمات قصيرة كثيرة في الأزرار والقوائم (مثل «تسجيل» أو «إلغاء»)، وهذا مجال ترتفع فيه نسبة الأخطاء في الترجمة الآلية عند غياب السياق. نوصي كحد أدنى بإجراء جولة مراجعة واحدة على الأقل يقوم فيها متحدث فعلي بتلك اللغة بتجربة الشاشات. كما أن الأهم قبل جودة الترجمة نفسها هو ضمان «عدم انهيار التخطيط عند ازدياد طول النص بعد الترجمة»، وذلك عبر استخدام TableLayoutPanel وAutoSize مسبقًا.
هل يجب ترجمة السجلات (Logs) ورسائل الأخطاء أيضًا؟
القاعدة المتعارف عليها عمليًا هي ترجمة الرسائل التي تظهر على شاشة المستخدم، وعدم ترجمة المحتوى المكتوب في ملفات السجلات (Log Files) أو سجل الأحداث (Event Log) (أي تثبيت لغة واحدة له). فالسجلات يقرأها المطورون والقائمون على التشغيل وليس المستخدمون، والسجلات متعددة اللغات تُفسد إمكانية البحث فيها عند التحقيق في المشكلات. كذلك، يجب تثبيت تنسيق السجلات (التاريخ والأرقام) على CultureInfo.InvariantCulture. وإذا صممت النظام بحيث يتم التعامل مع CurrentCulture وCurrentUICulture بشكل منفصل، فإن هذا الفصل بين الاستخدامين يتحقق بشكل طبيعي.
هل ينبغي جعل التطبيق قادرًا على تبديل اللغة بمعزل عن لغة عرض نظام التشغيل؟
في حالة النشر في فروع خارج اليابان، أو التطبيقات المؤسسية التي يستخدمها موظفون ناطقون بلغات أجنبية داخل اليابان، فإن وجود إعداد لغة خاص بالتطبيق له قيمة عالية. الأسلوب الآمن هو اعتماد نهج من مرحلتين: اتباع لغة عرض نظام التشغيل افتراضيًا (القيمة الافتراضية لـ CurrentUICulture)، والكتابة فوقها فقط عند اختيار المستخدم الصريح لها من شاشة الإعدادات. وجعل تطبيق التبديل يتم «عند إعادة التشغيل التالية» كمواصفة هو الخيار الأكثر أمانًا، إذ يُبسّط كلًا من التنفيذ وشرح طريقة الاستخدام.

الملف الشخصي للمؤلف

صفحة الملف الشخصي لمؤلف المقالة.

غو كومورا

مؤسّس شركة كومورا سوفت ذ.م.م.

يركّز على تطوير برامج ويندوز، والاستشارات التقنية، والتحقيق في الأخطاء، ويتميّز في المشاريع التي تبقى فيها الأصول القديمة ناشطة، وفي تشخيص الأعطال التي يصعب تحديد سببها.

روابط عامة

العودة إلى المدونة