سجل التعديلات (3 تحديثات، آخر تحديث 3 Sep، 2026)
سجل بالتغييرات التي أُجريت على هذا المقال. وحيثما حُفظت نسخة سابقة، تبقى متاحة للقراءة عبر رابط دائم يحمل معرّف DOI.
- أُضيفت روابط الاستشارة الموجودة في الأصل الياباني (consultation_services). ولم يتغيّر نصّ المقالة نفسه. قراءة النسخة السابقة لهذا التحديث (DOI: 10.5281/zenodo.22240863)
- أُعيدَت الترجمة العربية كترجمة كاملة عن النص الياباني الأصلي، وأُضيفَت خريطة المعرفة.
- أعيدت الترجمة كترجمة كاملة عن النص الياباني الأصلي. كانت النسخة العربية السابقة مختصراً يسقط أبواباً وجداول ورسوم Mermaid وتعليقات الأشكال وFAQ. أُعيدت هذه العناصر وفق الأصل الياباني، والادّعاءات التقنية مطابقة للنسخة اليابانية.
- النشر الأول
الاستشهاد بهذا المقال(DOI: 10.5281/zenodo.21621416)
هذا المقال محفوظ على Zenodo. يرد أدناه معرّف DOI الذي يشير دائمًا إلى أحدث نسخة، ومعرّف DOI المثبَّت على النسخة التي تقرؤها.
小村 豪 (2026). كيف نختار بين WinForms و WPF و WinUI - جدول قرار عملي. شركة كومورا سوفت ذ.م.م.. https://doi.org/10.5281/zenodo.21621416 https://comcomponent.com/ar/blog/2026/03/18/001-winforms-wpf-winui-decision-table/
- DOI (أحدث نسخة)
- 10.5281/zenodo.21621416
- DOI (هذه النسخة)
- 10.5281/zenodo.22279841
القارئ المستهدف: مطوّر تطبيقات سطح مكتب Windows بـ C# / .NET، ومن يحسم الاختيار التقني في ذلك الموقع. الافتراض: نستخدم .NET الحالي (لا .NET Framework)، والمنصة المستهدفة Windows فقط. طريقة القراءة: للخلاصة وحدها الفصل 1 والفصل 3. لحسم سياسة إطالة عمر تطبيق قائم الفصل 7. إذا أردت الحسم الأخير ابدأ من الفصل 8.
عندما ننشئ تطبيق سطح مكتب Windows بـ C# / .NET، ما يبقى دائماً معقّداً بهدوء هو اختيار أيّ من WinForms و WPF و WinUI.
ما هو خطر هنا طرق اختيار ضبابية من قبيل:
- WinUI لأنه الأحدث
- WinForms لأنه الأكثر اعتياداً
- WPF لأنه يبدو وسطاً بطريقة ما
flowchart TB
accTitle: خطر الاختيار الضبابي
accDescr: مخطّط يبيّن أن اختيار WinUI لأنه الأحدث أو WinForms لأنه الأكثر اعتياداً أو WPF لأنه يبدو وسطاً اختيار ضبابي خطر، وأن العمل ينظر بمحاور أوضح.
w1["WinUI لأنه أحدث"] --> w4["اختيار ضبابي"]
w2["WinForms لأنه معتاد"] --> w4
w3["WPF لأنه يبدو وسطاً"] --> w4
w4 --> w5["في العمل ننظر بمحاور أوضح"]
الشكل 1: لا نختار بـ «أحدث / معتاد / وسط»، بل بمحاور واضحة.
في العمل، المحاور التي ينبغي النظر إليها أوضح قليلاً.
- هل هو تطوير جديد، أم امتداد لأصل قائم
- هل الشاشة محورها نماذج إدخال، أم مطلوب منها التعبير
- هل الواجهة الحديثة بأسلوب Windows هي قيمة المنتج نفسها
- كيف ندير التوزيع والتحديث والتشغيل داخل المؤسسة
- هل أسلوب التطوير محورُه Windows Forms Designer، أم XAML / MVVM
في هذه المقالة نرتّب هذه المنطقة في صورة جدول قرار سهل الرؤية على ورقة واحدة. وللتوضيح، WinUI المقصود هنا يشير أساساً إلى WinUI 3 + Windows App SDK.12
كذلك هذه الثلاثة كلها مخصصة لـ Windows فقط. إن دخل macOS / Linux في نطاق الرؤية، فإن صياغة المسألة أصلاً تختلف.341
flowchart TB
accTitle: الثلاثة كلها مخصصة لـ Windows
accDescr: مخطّط يبيّن أن WinForms و WPF و WinUI كلها مخصصة لـ Windows، فإن دخل macOS أو Linux في النطاق تختلف صياغة المسألة أصلاً.
t1["WinForms"] --> t4["كلها مخصصة لـ Windows"]
t2["WPF"] --> t4
t3["WinUI"] --> t4
t4 -.-> t5["إن دخل macOS / Linux تختلف صياغة المسألة"]
الشكل 2: الثلاثة كلها مخصصة لـ Windows، فإن كان الهدف عبر المنصات فالمسألة مختلفة.
1. الخلاصة أولاً (بجملة)
بصيغة خشنة جداً لكنها مفيدة في العمل، الأمر هكذا.
- إذا كان تطبيق WinForms القائم كبيراً، ننظر أولاً إلى مواصلة WinForms كأساس
- إذا كان تطبيق WPF القائم كبيراً، ننظر أولاً إلى مواصلة WPF كأساس
- في أداة داخلية جديدة صغيرة إلى متوسطة، إذا كان المحور عناصر قياسية وشاشات إدخال ونريد البناء بسرعة، فإن WinForms لا يزال قوياً جداً35
- في تطبيق أعمال جديد متوسط إلى كبير بعدد شاشات كبير، إذا أردنا استخدام data binding والأنماط والقوالب والأوامر وMVVM بجدية، فإن WPF غالباً الأكثر أماناً467
- في منتج جديد مخصص لـ Windows، إذا كانت واجهة Windows الحديثة وFluent وتجربة Windows الأحدث مرتبطة مباشرة بقيمة المنتج، فإن WinUI قوي12
- إن أردنا استخدام أحدث Windows APIs فقط، فإن WinUI ليس ضرورياً. يمكن لـ WPF / WinForms أيضاً تضمين وظائف Windows App SDK28910
- الاختيار على فرض «يكفي أن ندخل WinUI تدريجياً لاحقاً» خطر قليلاً. حديث الترحيل المرحلي أوحل مما يُتوقَّع1011
باختصار، الأمر تقريباً كما يلي.
- إذا كان الأصل القائم كبيراً، فأبقِ على ذلك النَسَب أولاً
- في الجديد، إذا أردنا بناء نماذج قياسية بسرعة فـ WinForms
- في الجديد، إذا أردنا تطبيق أعمال Windows ينمو طويلاً فـ WPF
- في الجديد، إذا كانت واجهة Windows الحديثة نفسها هي المتطلب فـ WinUI
- إذا كنا نريد فقط استخدام Windows App SDK، فلا نجعل كل شيء WinUI دفعة واحدة
اختيار الإطار في الوقت ذاته اختيار لتقنية الواجهة و اختيار لتكاليف التوزيع والتشغيل والتعلّم والترحيل. إذا حُسم بمعيار «جديد / قديم» فقط، يرتد ذلك لاحقاً إلى تصميم التوزيع وتكلفة الصيانة.
flowchart TB
accTitle: طريقة حسم الخلاصة أولاً
accDescr: مخطّط يبيّن طريقة الحسم: إن كان الأصل القائم كبيراً نُبقي النَسَب أولاً، وفي الجديد إن كانت النماذج القياسية محوراً فـ WinForms، وإن كان تطبيق أعمال Windows ينمو طويلاً فـ WPF، وإن كانت الواجهة الحديثة نفسها متطلباً فـ WinUI.
r1{"هل الأصل القائم كبير؟"} -->|"نعم"| r2["أبقِ ذلك النَسَب أولاً"]
r1 -->|"لا، جديد"| r3{"هل المحور نماذج قياسية؟"}
r3 -->|"نعم"| r4["WinForms"]
r3 -->|"لا"| r5{"هل الواجهة الحديثة نفسها متطلب؟"}
r5 -->|"لا"| r6["WPF، تطبيق أعمال ينمو طويلاً"]
r5 -->|"نعم"| r7["WinUI"]
r7 -.-> r8["إن كان الغرض SDK فقط فلا WinUI شاملاً"]
الشكل 3: بالنظر بالترتيب إلى الأصل القائم وطبيعة الشاشة ومتطلب الواجهة الحديثة، تُحسم الخلاصة تقريباً.
في المخطّط، يشير الخطّ المتّصل إلى علاقة قائمة دائماً، ويشير الخطّ المتقطّع إلى علاقة مشروطة (شروط قيامها مذكورة في شرح كلّ علاقة في الصفحة التفصيليّة). القائمة الكاملة للعلاقات (المجموع 24، مع الأدلّة ودرجة اليقين) وتعريفات المفاهيم الرئيسة مجمّعة في صفحة تفاصيل خريطة المعرفة (باليابانية). البيانات: JSON-LD / Turtle
2. التقنيات الثلاث المقصودة في هذه المقالة
أولاً نوحّد المصطلحات قليلاً. الاختصارات التي ستظهر باستمرار نوسّعها هنا.
| المصطلح | التوسيع | بصورة مختصرة |
|---|---|---|
| XAML | eXtensible Application Markup Language | لغة ترميز مبنية على XML لكتابة بنية الشاشة تصريحياً. يستخدمها WPF و WinUI |
| Designer | Windows Forms Designer | وظيفة في Visual Studio لتركيب الشاشة بسحب العناصر. الناتج يبقى كشيفرة *.Designer.cs |
| Data Binding | data binding | آلية تربط خاصية على الشاشة بخاصية على جهة البيانات، فيتبع أحدهما الآخر عند التغيّر |
| MVVM | Model-View-ViewModel | نمط تصميم يفصل الشاشة (View)، وحالة الشاشة والأوامر (ViewModel)، ومنطق العمل والبيانات (Model). View و ViewModel يُربطان بـ Data Binding |
| Fluent | Fluent Design System | نظام تصميم Microsoft لمظهر Windows 11 وإحساس التشغيل. WinUI يفترضه |
| Windows App SDK | — | مجموعة مكتبات تطوير Windows الحالية وتشمل WinUI. لها وظائف غير الواجهة، ويمكن إضافتها أيضاً إلى تطبيقات WPF / WinForms / Win32 القائمة |
| XAML Islands | — | آلية لتضمين عناصر XAML جديدة في جزء فقط من تطبيق WPF / WinForms / Win32 قائم. التفاصيل في 5.3.3 |
| MSIX | — | صيغة حزمة تطبيقات Windows. التثبيت والتحديث وإلغاء التثبيت تُعالَج بآليات نظام التشغيل |
| package identity | معرّف الحزمة | حالة يستطيع فيها Windows تمييز العملية لأي حزمة تطبيق تنتمي. بعض وظائف Windows مثل الإشعارات والارتباطات لا تعمل من دونه |
| التقنية | بصورة مختصرة | المحور القوي |
|---|---|---|
| WinForms | واجهة .NET desktop تقليدية لـ Windows، يسهل بناء النماذج بسرعة عبر Visual Studio Designer | بناء الشاشات السريع، العناصر القياسية، الاستفادة من الأصل القائم |
| WPF | واجهة مخصصة لـ Windows يسهل عبرها صنع واجهة ذات تعبير قوي باستخدام XAML وdata binding والأنماط والقوالب والأوامر | تطبيقات الأعمال متوسطة إلى كبيرة، MVVM، سهولة تنظيم الشاشات |
| WinUI | واجهة أصلية حديثة لـ Windows تقوم على Windows App SDK | Fluent، أحدث تجارب Windows، DPI عالٍ، واجهة منتجات حديثة |
يُوصف WinForms في Microsoft Learn أيضاً بأنه إطار يتضمن عناصر ورسوماً وdata binding وإدخال المستخدم، ويسهل بناء التطبيقات عبر Designer بالسحب والإفلات داخل Visual Studio.3
WPF إطار واجهة عالي التعبير يشمل رسماً متجهاً مستقلاً عن الدقة، وXAML، وdata binding، وأنماطاً / قوالب، وثنائي / ثلاثي الأبعاد، وتحريكاً.4
WinUI جزء من Windows App SDK، وإطار واجهة لـ Windows الحالي يفترض DPI عالياً، وإدخالاً حديثاً، وتحريكاً سلساً، وتجربة عائلة Fluent.12 كذلك يملك مسار data binding / MVVM بشكل عادي.12
المهم هنا أن Windows App SDK و WinUI ليسا الشيء نفسه. WinUI هو جزء إطار الواجهة في Windows App SDK، لكن Windows App SDK نفسه يمكن إضافته أيضاً إلى تطبيقات WPF / WinForms / Win32 القائمة.210
لذا،
- استخدام WinUI
- استخدام وظائف Windows App SDK
يبدوان متشابهين وهما حكمان مختلفان. إذا اختلطا في النقاش، يُعامل «هل نرحّل الواجهة» و«هل نضيف وظيفة» كحديث واحد، فيصعب الخروج بخلاصة.
flowchart TB
accTitle: Windows App SDK و WinUI ليسا الشيء نفسه
accDescr: مخطّط يبيّن أن WinUI جزء إطار الواجهة في Windows App SDK، وأن SDK نفسه يمكن إضافته إلى تطبيقات WPF و WinForms و Win32 القائمة، لذا حكم استخدام WinUI وحكم استخدام وظائف SDK مختلفان.
sdk["Windows App SDK"] --> ui["WinUI، جزء إطار الواجهة فيه"]
sdk -.-> ex["يمكن إضافته أيضاً إلى WPF / WinForms / Win32"]
ui --> d1["حكم «استخدام WinUI»"]
ex --> d2["حكم «استخدام وظائف SDK»"]
d1 --> d3["متشابهان ظاهرياً ومختلفان"]
d2 --> d3
الشكل 4: «استخدام WinUI» و«استخدام وظائف Windows App SDK» حكمان مختلفان.
3. جدول القرار في ورقة واحدة
نضع أولاً الجدول الأسهل استخداماً في العمل.
| الوضع | ما نختاره أولاً | السبب |
|---|---|---|
| تعديل / إطالة عمر / تحديث إلى .NET لتطبيق WinForms قائم | مواصلة WinForms | يسهل الاستفادة من الشاشات القائمة وأصل Designer وأصل العناصر |
| تعديل / إطالة عمر / تحديث إلى .NET لتطبيق WPF قائم | مواصلة WPF | يسهل الاستفادة من XAML و Binding و MVVM وبنية الشاشات كما هي |
| جديد، أداة داخلية، شاشات إعداد، شاشات إدارة، محورها نماذج إدخال | WinForms | إن كان المحور عناصر قياسية فالإقلاع سريع |
| جديد، عدد شاشات كبير، حالة معقّدة، نريد أنماطاً / قوالب / MVVM | WPF | يسهل فصل مسؤوليات الشاشة وتنظيم الواجهة |
| جديد، واجهة Windows الحديثة نفسها متطلب | WinUI | يسهل الميل إلى Fluent وتجربة Windows الأحدث |
| الإبقاء على WPF / WinForms القائم واستخدام Toast / Windowing / App Lifecycle وغيرها | الإطار الحالي + Windows App SDK | غالباً لا يلزم ترحيل شامل للواجهة من أجل أحدث وظائف Windows |
| اعتماد كثيف على COM / ActiveX / عناصر طرف ثالث قديمة | أقرب إلى الإطار القائم | تكلفة ترحيل الاعتماد أكبر من الواجهة |
| ظروف التوزيع والتحديث والتشغيل داخل المؤسسة قوية | أولوية النظر إلى WPF / WinForms، وWinUI بعد تأكيد تصميم التوزيع مبكراً | WinUI يحتاج النظر مبكراً إلى مسائل Windows App SDK / packaging |
| نريد لاحقاً عبور المنصات | إعادة النظر بما يشمل غير هذه الثلاثة | هذه الثلاثة كلها مخصصة لـ Windows |
هذا الجدول وحده يكفي تقريباً، لكن نقطتين تبقيان مربكتين.
- في تطبيق أعمال Windows جديد، نميل إلى WinForms أم WPF
- هل نذهب إلى WinUI رغم وجود WPF / WinForms قائم
هاتان تسهلان الحكم بالنظر إلى جداول المقارنة التالية.
flowchart TB
accTitle: نقطتان تبقيان بعد جدول القرار
accDescr: مخطّط يبيّن أن جدول القرار الواحد يُبقي مسألتين: الميل في تطبيق أعمال جديد إلى WinForms أو WPF، وما إذا نذهب إلى WinUI رغم وجود أصل، فيُفكَّر فيهما بجداول المقارنة حسب الزاوية.
hyo["جدول قرار في ورقة واحدة"] --> n1["تطبيق أعمال جديد: WinForms أم WPF"]
hyo --> n2["هل نذهب إلى WinUI رغم وجود أصل"]
n1 --> hik["نفكّر بجداول المقارنة حسب الزاوية"]
n2 --> hik
الشكل 5: النقطتان المتبقيتان بعد جدول القرار تُفكَّران بجداول المقارنة حسب الزاوية.
4. جداول مقارنة حسب الزاوية
هنا ليست جدول تفوّق رسمي، بل مقارنة أقرب كثيراً إلى العمل.
| الزاوية | WinForms | WPF | WinUI |
|---|---|---|---|
| بناء نموذج إدخال صغير بسرعة | ◎ | ○ | ○ |
| أداة داخلية محورها عناصر قياسية | ◎ | ○ | △〜○ |
| التوافق مع data binding / MVVM | △ | ◎ | ○〜◎ |
| الأنماط / القوالب / قدرة التعبير في الشاشة | △ | ◎ | ◎ |
| التآلف مع أصل سطح مكتب Windows القائم | ◎ | ○ | △ |
| الإحساس الحديث بأسلوب Windows | △ | ○ | ◎ |
| إطالة عمر الشاشات القائمة والتعديل المرحلي | ◎ | ◎ | △ |
| إضافة وظائف Windows App SDK فقط | ○ | ○ | ◎ |
| خفة تصميم التوزيع / التحديث / التشغيل | ○ | ○ | △〜○ |
| صنع «واجهة منتج Windows مخصص ينمو طويلاً وجديداً» | △ | ○ | ◎ |
سر القراءة ليس ما هو الأقوى بل ما هو الأقل احتكاكاً.
مثلاً،
- أداة إعداد داخلية
- شاشة إعداد جهاز
- قائمة، تفاصيل، بحث، إعداد، أزرار
- استقرار التشغيل وسرعة التعديل أهم من المظهر
فعندها WinForms لا يزال معقولاً بما يكفي.
وبالعكس،
- عدد شاشات كبير
- تبديل حالات العرض كثير
- نريد فصل View عن المنطق
- نريد ربط تغيّر البيانات بالواجهة بشكل طبيعي
- نريد ضبط الواجهة بأنماط / قوالب
وأيضاً،
- نريد افتراض مظهر Windows 11
- نريد الاستفادة من Fluent بصدق
- نريد افتراض DPI عالٍ ولمس وواجهات نوافذ حديثة
- جديد، وانطباع الواجهة مهم أيضاً كمنتج مخصص لـ Windows
flowchart TB
accTitle: الاختيار بقلة الاحتكاك
accDescr: مخطّط يبيّن سر النظر إلى ما هو الأقل احتكاكاً لا الأقوى: أداة داخلية محورها عناصر قياسية تناسب WinForms، ومشروع بعدد شاشات كبير يريد MVVM يناسب WPF، ومشروع يفترض Fluent وتجربة Windows الحديثة يناسب WinUI.
k0["ما هو الأقل احتكاكاً"] --> k1["أداة داخلية محورها عناصر قياسية"]
k0 --> k2["عدد شاشات كبير ونريد MVVM"]
k0 --> k3["Fluent وتجربة Windows الحديثة مفترضة"]
k1 --> k4["WinForms"]
k2 --> k5["WPF"]
k3 --> k6["WinUI"]
الشكل 6: نوزّع الثلاثة لا بـ «ما هو الأقوى» بل بـ «ما هو الأقل احتكاكاً».
4.1 رؤية «فرق قدرة التعبير» بأقل شيفرة
بند «التوافق مع data binding / MVVM» في الجدول أعلاه يصعب الإمساك به بالكلام وحده. نرتّب بأقل شيفرة ماذا يتغيّر إذا كتبنا الشاشة نفسها بـ WinForms و WPF.
ما نبنيه شاشة «مربع نص واحد وزر حفظ واحد» فقط.
WinForms: الـ Designer يولّد *.Designer.cs، وفي معالج الحدث نأخذ القيمة من الشاشة.
// MainForm.Designer.cs — Designer が生成する側。手で書く場所ではありません
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Button saveButton;
private void InitializeComponent()
{
this.nameTextBox = new System.Windows.Forms.TextBox();
this.saveButton = new System.Windows.Forms.Button();
this.SuspendLayout();
this.nameTextBox.Location = new System.Drawing.Point(12, 12);
this.nameTextBox.Size = new System.Drawing.Size(200, 23);
this.saveButton.Location = new System.Drawing.Point(218, 12);
this.saveButton.Size = new System.Drawing.Size(75, 23);
this.saveButton.Text = "حفظ";
this.saveButton.Click += new System.EventHandler(this.SaveButton_Click);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.saveButton);
this.ResumeLayout(false);
}
// MainForm.cs — こちらが手で書く側
public partial class MainForm : Form
{
private readonly EditorService _service;
public MainForm(EditorService service)
{
_service = service;
InitializeComponent();
}
private void SaveButton_Click(object sender, EventArgs e)
{
// 画面のコントロールから直接値を取り出して渡す
_service.Save(this.nameTextBox.Text);
}
}
WPF: في XAML نكتب فقط «بماذا يرتبط»، وإدخال القيم وإخراجها يتولاه Binding.
<!-- MainWindow.xaml -->
<Window x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="تحرير" Width="360" Height="120">
<StackPanel Orientation="Horizontal" Margin="12">
<TextBox Width="200"
Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
<Button Width="75" Margin="6,0,0,0" Content="حفظ"
Command="{Binding SaveCommand}" />
</StackPanel>
</Window>
// MainWindow.xaml.cs — DataContext を渡すのを忘れると Binding は何も起きません
public partial class MainWindow : Window
{
public MainWindow(EditorService service)
{
InitializeComponent();
this.DataContext = new MainViewModel(service);
}
}
// MainViewModel.cs — 画面を知らない側。単体テストもここで書けます
public sealed class MainViewModel : INotifyPropertyChanged
{
private readonly EditorService _service;
private string _name = string.Empty;
public MainViewModel(EditorService service)
{
_service = service;
SaveCommand = new RelayCommand(() => _service.Save(Name));
}
public string Name
{
get => _name;
set
{
if (_name == value) return;
_name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
}
}
public ICommand SaveCommand { get; }
public event PropertyChangedEventHandler PropertyChanged;
}
RelayCommand صنف صغير ينفّذ ICommand، موجود في مكتبات مثل CommunityToolkit.Mvvm، ويمكن كتابته ذاتياً في نحو 20 سطراً.
بعدد الأسطر وحده WPF أكثر. الفرق يظهر من هنا.
| WinForms | WPF | |
|---|---|---|
| مكان أخذ القيمة من الشاشة | قراءة nameTextBox.Text مباشرة داخل معالج الحدث |
خاصية Name. لا نلمس View |
| اختبار وحدة لمعالجة الحفظ | يلزم إنشاء Form | يمكن استدعاء MainViewModel مباشرة بـ new |
| إظهار حقل الإدخال نفسه في شاشة أخرى | إعادة وضع العنصر وإعادة كتابة المعالج | تطبيق View آخر على ViewModel نفسه |
| توحيد المظهر عبر كل الشاشات | محاذاة خصائص كل عنصر على حدة | وضع Style / Template في موضع واحد |
المعنى العملي لهذا الفرق: إن كانت الشاشات 3 فـ WinForms أسرع، وإن صارت 30 فـ WPF أخف.
flowchart TB
accTitle: فرق مسار القيمة
accDescr: مخطّط يبيّن أن WinForms يأخذ معالج الحدث القيمة مباشرة من عنصر الشاشة ويمرّرها إلى الخدمة، بينما في WPF يربط Binding بين View و ViewModel، و ViewModel الذي لا يعرف الشاشة يستدعي الخدمة.
subgraph wf["WinForms"]
a1["عنصر View"] --> a2["معالج الحدث"]
a2 --> a3["استدعاء الخدمة مباشرة"]
end
subgraph wp["WPF"]
b1["XAML في View"] --> b2["Binding"]
b2 --> b3["ViewModel"]
b3 --> b4["استدعاء الخدمة"]
end
a3 -.-> c1["أسرع إن كانت الشاشات 3"]
b4 -.-> c2["أخف حتى إن كانت الشاشات 30"]
الشكل 7: WinForms يأخذ القيمة مباشرة من الشاشة، و WPF يتولاها ViewModel عبر Binding.
5. أي نوع من المشاريع يناسب كلاً منها
5.1 WinForms
WinForms يُستخف به أحياناً بلا وجه، لكن في نقطة واحدة هي بناء شاشات أعمال محورها عناصر قياسية بسرعة لا يزال لا يُستهان به.35
ما يناسبه خصوصاً مشاريع من هذا النوع مثلاً.
- أداة إعداد داخلية
- شاشة إعداد جهاز / أداة قياس / أداة مراقبة
- شاشة إدارة، شاشة بحث، قائمة + تفاصيل
- مشروع أصله WinForms كبير
- فريق أسلوب تطويره محورُه Windows Forms Designer
قوة WinForms أنه حتى من دون إدخال فكر صعب تظهر شاشة قريبة من المنتج النهائي بسرعة معقولة. نماذج، أزرار، تسميات، مربعات نص، شبكة بيانات. إن كان هذا هو ميدان المعركة، يمكن القتال جيداً.
لكن نقاط الضعف واضحة أيضاً.
- نريد توحيد مظهر الشاشة كلها بقوة
- نريد ضبط الواجهة بأنماط وقوالب
- نريد معالجة تغيّر حالة معقّد بمحور data binding
- نريد فصل منطق الشاشة بشكل نظيف
هذه الناحية أصرح في WPF أو WinUI.
إذا صنعنا تطبيقاً كبيراً بـ WinForms، يسهل إن تراخينا أن يصير غابة معالجات أحداث. لذا إن اخترنا WinForms،
- الإبقاء على مسؤوليات الشاشة صغيرة
- الفصل بوحدات UserControl
- الوعي بحدود تعادل Presenter / ViewModel
- عدم كتابة منطق العمل ملتصقاً بأحداث الشاشة
يجدر حسم هذا من البداية ليبقى الأمر سلاماً.
flowchart TB
accTitle: تجنّب غابة معالجات الأحداث
accDescr: مخطّط يبيّن أن تطبيق WinForms الكبير يسهل أن يصير غابة معالجات أحداث، لذا يُحسم من البداية الإبقاء على مسؤوليات الشاشة صغيرة والفصل بوحدات UserControl والوعي بالحدود.
mo["تطبيق WinForms كبير"] --> ha["يسهل أن يصير غابة معالجات أحداث"]
ha --> p1["الإبقاء على مسؤوليات الشاشة صغيرة"]
ha --> p2["الفصل بوحدات UserControl"]
ha --> p3["الوعي بالحدود"]
p3 -.-> p4["عدم كتابة منطق العمل في أحداث الشاشة"]
الشكل 8: تطبيق WinForms الكبير يصبح أسلم إذا حُسمت ممارسة فصل المسؤوليات من البداية.
وثمة أمر مهم جداً في العمل: لا يلزم التخلي عن WinForms لأننا نريد استخدام Windows App SDK. رسمياً أيضاً يوجد مسار لإضافة وظائف Windows App SDK إلى تطبيق WinForms قائم.910
أي أن WinForms يمكن اختياره كالتالي.
- الواجهة كما هي
- تحديث وظائف Windows اللازمة فقط
هذه نقطة تسوية واقعية.
flowchart TB
accTitle: مسار التحديث مع الإبقاء على WinForms
accDescr: مخطّط يبيّن أنه لا يلزم التخلي عن WinForms لأننا نريد Windows App SDK، وأن هناك نقطة تسوية واقعية تبقي الواجهة وتحدّث الوظائف اللازمة فقط.
g1["نريد استخدام Windows App SDK"] --> g2["لا يلزم التخلي عن WinForms"]
g2 --> g3["الواجهة كما هي"]
g2 --> g4["تحديث الوظائف اللازمة فقط"]
g3 --> g5["نقطة تسوية واقعية"]
g4 --> g5
الشكل 9: يستطيع WinForms تحديث وظائف Windows اللازمة مع الإبقاء على الواجهة.
5.2 WPF
WPF إذا نُظر إليه كواجهة .NET لسطح مكتب Windows هو النواة الأكثر توازناً.4
نقاط القوة واضحة.
- كتابة الشاشة تصريحياً بـ XAML
- Data Binding قوي
- يمكن استخدام Style / Template
- يمكن استخدام Command
- يسهل فصل View عن المنطق
- يسهل تنظيم شاشات متوسطة إلى كبيرة
حتى الوثائق الرسمية لـ WPF تشرح data binding كوظيفة مركزية، وترتب الأوامر كآلية تفصل الإدخال عن منطق التنفيذ.67
لذا يناسب مشاريع من هذا النوع مثلاً.
- تطبيق أعمال بعدد شاشات كبير
- كثير من القوائم والتفاصيل والتحرير والبحث وعرض الحالة
- تطبيق Windows يصونه عدة أشخاص طويلاً
- نريد فصل View عن المنطق
- نريد في التعديلات المستقبلية فصل مسؤولية المظهر عن السلوك
- WinForms قد يثقّل الشاشة بسرعة
عندما نحتار في تطبيق أعمال جديد مخصص لـ Windows، WPF لا يزال المرشح الأول الآمن. قطعه بـ «WPF قديم إذن لا» خشونة زائدة قليلاً.
flowchart TB
accTitle: المرشح الأول الآمن لتطبيق أعمال جديد
accDescr: مخطّط يبيّن أن تطبيق أعمال Windows متوسط إلى كبير بعدد شاشات كبير، ويريد فصل View عن المنطق، ويصونه عدة أشخاص طويلاً، لا يزال WPF مرشحه الأول الآمن.
j1["تطبيق أعمال بعدد شاشات كبير"] --> j4["WPF المرشح الأول الآمن"]
j2["نريد فصل View عن المنطق"] --> j4
j3["صيانة طويلة بعدة أشخاص"] --> j4
j4 -.-> j5["قطعه بـ «قديم إذن لا» خشونة"]
الشكل 10: في تطبيق أعمال جديد بعدد شاشات كبير وصيانة طويلة، يكون WPF المرشح الأول الآمن.
بل إن،
- يوجد أصل WPF قائم
- توجد معرفة XAML / MVVM قائمة
- Fluent ليس الأولوية القصوى إلى ذلك الحد
- لكن نريد تصميم واجهة أنظف من WinForms
فعندها أن يكون WPF الأفضل مساراً أمر شائع.
بالطبع لـ WPF أيضاً عاداته.
- الإفراط في تعقيد XAML يصعّب القراءة
- تكديس عناصر مخصصة وقوالب يثقّل الصيانة
- الميل المفرط إلى «حل كل شيء بـ Binding» قد يصعّب بالعكس تتبّع مسار المعالجة
هذه موجودة فعلاً، لكنها ليست أن WPF سيئ بقدر ما هي أن الأداة ذات التعبير القوي إذا هُزّت بخشونة يكون رد الفعل كبيراً أيضاً.
حتى في WPF يمكن إضافة بعض وظائف Windows App SDK. أي أن هناك مساراً لتحديث وظائف Windows مع الإبقاء على WPF.810
لذلك،
- التخلي عن WPF كله والترحيل الشامل إلى WinUI
أقل انتصاراً في العمل غالباً من:
- تقريب WPF إلى .NET الحالي
- إضافة وظائف Windows اللازمة فقط بـ Windows App SDK
- تنظيم التركيبة بدءاً من الوظائف الجديدة الكبيرة
flowchart TB
accTitle: التدرّج أفضل من الترحيل الشامل لـ WPF
accDescr: مخطّط يبيّن أن تقريب WPF إلى .NET الحالي وإضافة الوظائف اللازمة فقط بـ Windows App SDK وتنظيم التركيبة من الوظائف الجديدة الكبيرة ينتصر في العمل أكثر من التخلي عن WPF كله والترحيل الشامل إلى WinUI.
z1["تقريب WPF إلى .NET الحالي"] --> z2["إضافة الوظائف اللازمة فقط بـ SDK"]
z2 --> z3["التنظيم بدءاً من الوظائف الجديدة الكبيرة"]
z3 -.-> z4["ينتصر أكثر من الترحيل الشامل"]
الشكل 11: في WPF التدرّج بتقريبه إلى .NET الحالي وإضافة الوظائف ينتصر أكثر من الترحيل الشامل.
5.3 WinUI
WinUI هو المرشح الحديث الجاد عند صنع تطبيق جديد مخصص لـ Windows.12
رسمياً موقعه:
- محسَّن لأحدث العتاد والإدخال
- DPI عالٍ
- تحريك سلس
- جزء من Windows App SDK
.1
لذا يناسب مشاريع من هذا النوع.
- منتج جديد مخصص لـ Windows
- انطباع الواجهة والتجربة نفسها مهم
- نريد استخدام Fluent بصراحة
- نريد الميل إلى موقع Windows 11 الحالي
- نريد افتراض واجهات نوافذ جديدة وتجربة Windows الأحدث
المشروع الذي يملك سبباً حقيقياً لاختيار WinUI هو تقريباً مشروع ليس «المظهر جديد» بل «نريد إدخال تجربة Windows الحالية في المنتج».
flowchart TB
accTitle: كيف نميّز سبب اختيار WinUI
accDescr: مخطّط يبيّن أن المشروع الذي يملك سبباً حقيقياً لاختيار WinUI ليس لأن المظهر جديد، بل لأنه يريد إدخال تجربة Windows الحالية في المنتج.
y1["مشروع يملك سبب اختيار WinUI"] --> y2["ليس «المظهر جديد»"]
y2 --> y3["«تجربة Windows الحالية في المنتج»"]
y3 -.-> y4["منتج جديد مخصص لـ Windows وانطباع الواجهة مهم"]
الشكل 12: سبب اعتماد WinUI ليس «الحداثة» بل «إدخال تجربة Windows الحالية».
من جهة أخرى هناك نقاط انتباه.
5.3.1 WinUI ليس «مجرد WPF أحدث»
يبدو قريباً لأنه يستخدم XAML، لكن يختلف:
- API الأساسي
- عالم العناصر
- تركيبة المشروع
- تفكير التوزيع / packaging
- علاقة Windows App SDK
أي أن اعتباره بديلاً سهلاً عن WPF خطر قليلاً.
flowchart TB
accTitle: WinUI ليس مجرد WPF أحدث
accDescr: مخطّط يبيّن أنه رغم الشبه لاستخدام XAML، يختلف API الأساسي وعالم العناصر وتركيبة المشروع وتفكير التوزيع وpackaging وعلاقة SDK، فاعتباره بديلاً سهلاً عن WPF خطر.
u1["يبدو قريباً لأنه يستخدم XAML"] --> u2["لكن مواضع الاختلاف كثيرة"]
u2 --> u3["API الأساسي والعناصر"]
u2 --> u4["التركيبة و packaging"]
u2 --> u5["علاقة SDK"]
u5 -.-> u6["اعتباره بديلاً سهلاً خطر"]
الشكل 13: حتى مع XAML نفسه، WinUI ليس بديلاً سهلاً عن WPF.
5.3.2 اختيار WinUI يقدّم حديث التوزيع إلى الواجهة
تطبيق WinUI 3 packaged افتراضياً. من جهة أخرى يعالج Windows App SDK نفسه packaged و unpackaged كليهما.13142
المهم هنا أن الأفضل حسم التالي مبكراً:
- كيف نوزّع
- كيف نُدخل وقت التشغيل
- هل يلزم package identity
- توزيع داخلي، أم Store، أم MSIX، أم مسار EXE / MSI قائم
لكن «أكّد مبكراً» وحده يصعب معه معرفة ماذا ننظر إليه، لذا نضع مضمون التحقق هنا.
- packaging: هل يملك التطبيق package identity
- runtime: هل نستخدم Windows App SDK كـ framework-dependent أم نضمّنه self-contained
flowchart TB
accTitle: محوران يُحسمان أولاً
accDescr: مخطّط يبيّن أنه في توزيع WinUI يُحسم أولاً محور packaging: هل يملك التطبيق package identity، ومحور runtime: هل يُستخدم Windows App SDK كـ framework-dependent أم يُضمَّن self-contained.
h1["تصميم التوزيع"] --> h2["محور packaging"]
h1 --> h3["محور runtime"]
h2 -.-> h4["هل يملك package identity"]
h3 -.-> h5["framework-dependent أم تضمين"]
الشكل 14: في التوزيع نحدد أولاً محوري packaging و runtime.
خيارات جهة packaging ثلاثة.13
| النموذج | package identity | المثبّت | المشهد المناسب |
|---|---|---|---|
| packaged (MSIX) | موجود | MSIX يحل محل المثبّت | تطوير جديد، نشر Store، توزيع مؤسسي عبر Intune وغيرها |
| packaged يشير إلى موقع خارجي (sparse package) | موجود | استخدام المثبّت القائم كما هو | Win32 / WPF / WinForms قائم يملك مثبّتاً خاصاً |
| unpackaged | غير موجود | MSI / EXE / xcopy | أداة داخلية، Win32 تقليدي يُوزَّع على نطاق واسع |
ثم نحكم من جهة الوظائف هل يلزم package identity. الوظائف التي تنص الوثائق الرسمية أنها «لا تعمل بلا package identity» مثلاً هذه الناحية.13
- مهام الخلفية
- إشعارات الدفع (WNS)
- هدف المشاركة
- توسيع قائمة سياق المستكشف
- ارتباط أنواع الملفات ومخططات URI
- مهام بدء التشغيل
- App Service
- Windows AI API
إجراء التحقق بهذا الترتيب عملي.
- الاستنتاج من المتطلبات. هل يُخطَّط لاستخدام وظيفة من القائمة أعلاه. إن وُجدت واحدة يلزم جهة packaged.
- هل يمكن التخلي عن المثبّت القائم. إن لم نُرد التخلي، فالجواب ليس ترحيلاً شاملاً إلى MSIX بل packaged يشير إلى موقع خارجي. تبقى مواضع الثنائيات وآلية التحديث كما هي، وتُضاف الهوية فقط.13
- التحقق وقت التشغيل. هل للعملية الجارية هوية يمكن الحكم عليه بـ
GetCurrentPackageFullName. إن لم تكن هوية يعودAPPMODEL_ERROR_NO_PACKAGE. وبالعكس، إن استدعيت Windows API وعادE_ILLEGAL_METHOD_CALLأوAPPMODEL_ERROR_NO_PACKAGEفذلك علامة الاصطدام بمتطلب package identity.13 - التحقق على الجهاز. الحزم المثبّتة يمكن سردها بـ
Get-AppxPackageفي PowerShell. - أخيراً نحدد runtime. إن أردنا التوزيع بـ xcopy أو zip فالمسار الافتراضي self-contained، وإن أخرجنا إلى Store فـ framework-dependent.15
التوزيع مهم أيضاً في WinForms / WPF، لكن في WinUI يسهل أن يتقدّم هذا إلى الواجهة. تطبيق WinUI 3 جديد packaged افتراضياً، فإن لم يُحسَم شيء يركب مسار MSIX تلقائياً.13 ما حسبناه تحديداً للواجهة كان في الواقع تحديداً لاستراتيجية التوزيع، وهذه ناحية معقّدة قليلاً في هذا العالم.
flowchart TB
accTitle: إجراء التحقق من package identity
accDescr: مخطّط يبيّن إجراء تحقق من خمس خطوات: الاستنتاج من المتطلبات هل تلزم وظائف package identity، وهل يمكن التخلي عن المثبّت، والتحقق وقت التشغيل وعلى الجهاز، وأخيراً تحديد runtime.
s1["1. الاستنتاج من المتطلبات"] --> s2["2. هل يمكن التخلي عن المثبّت"]
s2 --> s3["3. التحقق وقت التشغيل"]
s3 --> s4["4. التحقق على الجهاز"]
s4 --> s5["5. تحديد runtime"]
s2 -.-> s6["إن لم نُرد التخلي: packaged يشير إلى موقع خارجي"]
s3 -.-> s7["الحكم بـ GetCurrentPackageFullName"]
الشكل 15: لزوم package identity يُتحقق منه بهذا الترتيب: المتطلبات، المثبّت، وقت التشغيل، الجهاز.
5.3.3 «خلط WinUI تدريجياً في WPF / WinForms القائم» يُجرَّب أولاً
هنا يسهل أن ينتفخ التوقع. لكن حتى FAQ من Microsoft مكتوب بروح أن WinUI غالباً لا يُستخدم ما لم نكن مستعدين لترحيل إطار الواجهة بالكامل. وحول XAML Islands أيضاً، بينما تُظهر الوثائق الرسمية مسار التضمين في تطبيقات سطح المكتب القائمة، تقول ملاحظات إصدار Windows App SDK 1.4 إن الاستخدام في تطبيقات C++ هو المختبَر أساساً حالياً، ولا تدخل عناصر غلاف مريحة موجّهة إلى WPF / WinForms.1011
أي أن:
- «يبدو أن الترحيل المرحلي ممكن»
- «يبدو أن التضمين التدريجي يكفي»
جذاب كتصور، لكن الأفضل التحقق بنطاق صغير قبل جعله الاستراتيجية الرئيسة للمشروع.
WinUI أفضل مساراً عندما:
- نبدأ جديداً
- نصنع تجربة كمنتج مخصص لـ Windows
وبالعكس، كوعاء للاستبدال الشامل لـ WPF / WinForms القائم يحتاج سبباً وتحققاً.
flowchart TB
accTitle: الترحيل المرحلي يُتحقق منه قبل جعله استراتيجية رئيسة
accDescr: مخطّط يبيّن أن خلط WinUI تدريجياً جذاب كتصور، لكن FAQ يقول إنه غالباً لا يُستخدم ما لم نكن مستعدين للترحيل الكامل، وXAML Islands بلا غلاف مريح لـ WPF/WinForms، لذا يُتحقق بنطاق صغير قبل الاستراتيجية الرئيسة.
v1["نريد خلط WinUI تدريجياً"] --> v2["جذاب كتصور"]
v2 --> v3["FAQ بروحه يفترض الترحيل الكامل"]
v3 --> v4["لا غلاف موجّه إلى WPF / WinForms"]
v4 --> v5["تحقق صغير قبل الاستراتيجية الرئيسة"]
الشكل 16: «خلط WinUI تدريجياً» يُتحقق منه بنطاق صغير قبل جعله استراتيجية رئيسة.
6. أخطاء حكم شائعة
6.1 «WinUI لأنه الأحدث»
هذا مفهوم، لكنه خطر جداً.
سبب اختيار تقنية جديدة أفضل أن يُنظر إليه من زاوية هل توجد قيمة لا تُنال إلا بتلك التقنية.
- هل تجربة Windows الحديثة قيمة المنتج
- هل نريد استخدام Fluent بصراحة
- هل هو منتج جديد
- هل يمكن قبول افتراضات التوزيع / التشغيل
إن كانت نعم فـ WinUI قوي. وبالعكس، «يبدو أن له مستقبلاً» وحده يجعل تفسير التكلفة ضعيفاً.
flowchart TB
accTitle: نختار بالقيمة لا بـ «لأنه الأحدث»
accDescr: مخطّط يبيّن أن سبب اختيار تقنية جديدة يُنظر إليه من وجود قيمة لا تُنال إلا بها، فإن كانت نعم فـ WinUI قوي، و«يبدو أن له مستقبلاً» وحده يجعل تفسير التكلفة ضعيفاً.
q0["سبب اختيار تقنية جديدة"] --> q1{"هل توجد قيمة لا تُنال إلا بتلك التقنية؟"}
q1 -->|"نعم"| q2["WinUI قوي"]
q1 -->|"«يبدو أن له مستقبلاً» فقط"| q3["تفسير التكلفة ضعيف"]
الشكل 17: لا نختار بـ «لأنه الأحدث» بل بوجود قيمة لا تُنال إلا بتلك التقنية.
6.2 «يجب الانتقال إلى WinUI لأننا نريد Windows App SDK»
هذا يسهل سوء فهمه، لكنه غير صحيح.
يمكن إضافة Windows App SDK أيضاً إلى WPF / WinForms القائم. حتى FAQ الرسمي يرتّب أن تطبيقات WPF / MFC / WinForms تستطيع استخدام Windows App SDK APIs غير المرتبطة بـ WinUI.1089
مثلاً وظائف مثل:
- App Lifecycle
- Windowing
- Toast Notifications
قد تُدمَج مع الإبقاء على الواجهة الحالية.10
6.3 «WPF / WinForms انتهيا»
هنا أيضاً لا تقطعهما بخشونة.
WinForms و WPF مستمران في التوثيق ومسارات الترحيل على .NET الحالي، وتعاملهما الوثائق الرسمية كواجهات سطح مكتب Windows حالية.34
كمادة حكم للصيانة طويلة الأمد، أوضح من «هل بقيت وثائق» هو هل تستمر الميزات الجديدة في الدخول. من هذه الزاوية وضع الثلاثة كالتالي.
| الحركة الأخيرة | القراءة | |
|---|---|---|
| WPF | في .NET 9 أُضيف سمة Fluent موجّهة إلى Windows 11، ويمكن التبديل بين light / dark / system بخاصية ThemeMode. يدعم أيضاً لون تمييز Windows16 |
سبب «إلى WinUI لأن المظهر قديم» أضعف مما كان |
| WinForms | في .NET 9 دخل دعم مؤقت للوضع الداكن، ويُبدَّل بـ Application.SetColorMode. لكن هذه ميزة تجريبية، ومكتوب أن الدعم الرسمي يستهدف .NET 10. زادت أيضاً واجهات غير متزامنة17 |
ميزات جديدة تدخل، لكن يختلط فيها ما يحمل علماً تجريبياً |
| WinUI / Windows App SDK | يستمر التحديث بدورة إصدار مستقلة عن .NET18 | التحديث نشط، لكن يلزم تتبّعه منفصلاً عن إصدار .NET فيزيد بنداً في خطة الصيانة |
أي أن القراءة من زاوية الصيانة طويلة الأمد كالتالي.
- WPF و WinForms ليسا «مجمَّدين ومتروكين»، بل تدخل فيهما ميزات محمولة على إصدار .NET السنوي. لكن ميزات WinForms البارزة منها ما هو في مرحلة تجريبية، فيلزم تأكيد توقيت الاعتماد.
- اختيار WinUI يعني إدارة أجل دعم .NET وأجل دعم Windows App SDK كلٌّ على حدة. في المشاريع طويلة الأمد يؤثّر هذا بهدوء.
- أياً اخترنا، لا ضمان «يعمل عشر سنوات بلا تعديل»، لذا حسم إلى أي إصدار نتابع أولاً أكثر عملية.
flowchart TB
accTitle: قراءة الصيانة طويلة الأمد
accDescr: مخطّط يبيّن أن WPF و WinForms تدخل فيهما ميزات محمولة على إصدار .NET السنوي، وأن اختيار WinUI يعني إدارة أجل SDK منفصلاً عن .NET، لذا يُحسم أولاً إلى أي إصدار نتابع.
m1["WPF / WinForms"] --> m2["ميزات تدخل محمولة على إصدار .NET"]
m3["WinUI"] --> m4["إدارة أجل SDK على حدة"]
m2 --> m5["حسم مدى المتابعة أولاً"]
m4 --> m5
الشكل 18: في الصيانة طويلة الأمد ننظر على أي شيء تركب التحديثات، ونحدد سياسة المتابعة أولاً.
خصوصاً في تطبيقات الأعمال، غالباً ما يكون:
- الأصل القائم
- عناصر الطرف الثالث
- عدد الشاشات
- التقارير والطباعة
- الربط بالأجهزة
- إجراءات التوزيع
أثقل من حداثة إطار الواجهة.
6.4 «ما دام الأمر كذلك فإعادة كتابة شاملة»
إعادة الكتابة الشاملة أقرب إلى حكم أعمال منها إلى اختيار تقني.
إن وُجد تطبيق قائم، ما ينبغي النظر إليه أولاً هذه الناحية.
- ما الذي يزعج حقاً
- هل هي مشكلة واجهة أم مشكلة معمارية
- أليست اعتمادات DLL / COM / OCX / التقارير / التوزيع هي الثقل الحقيقي
- هل تُحل المشكلة دون تغيير الواجهة كلها
إعادة كتابة الواجهة استعراضية، والتكلفة أيضاً استعراضية. علاوة على ذلك، حتى لو صار المظهر جديداً، تعقيد المحيط يبقى غالباً.
flowchart TB
accTitle: أربعة أسئلة قبل إعادة الكتابة الشاملة
accDescr: مخطّط يبيّن أن إعادة الكتابة الشاملة أقرب إلى حكم أعمال، فينظر أولاً إلى ما يزعج حقاً، وهل هي واجهة أم معمارية، وهل الاعتمادات والتوزيع هي الثقل، وهل تُحل دون تغيير الواجهة كلها.
r1["1. ما الذي يزعج حقاً"] --> r2["2. واجهة أم معمارية"]
r2 --> r3["3. أليست الاعتمادات والتوزيع ثقلاً"]
r3 --> r4["4. هل تُحل دون تغيير الواجهة"]
r4 -.-> r5["إعادة الكتابة تكلفتها أيضاً استعراضية"]
الشكل 19: قبل حسم إعادة الكتابة الشاملة نتأكد بأربعة أسئلة من هوية المشكلة.
6.5 «لاحقاً نُصلح الأمر بـ XAML Islands»
هذا التوقع مفهوم. لكن الأسلم ألا نعامله من البداية كقارب نجاة.1011
الترحيل المرحلي الأفضل تجربة صغيرة أولاً لـ:
- أي عنصر نريد تضمينه
- ماذا يحدث للتركيز والإدخال وDPI والسمة
- هل تكوين المضيف ذلك مستقر فعلاً
flowchart TB
accTitle: XAML Islands يُجرَّب صغيراً أولاً
accDescr: مخطّط يبيّن أنه في الترحيل المرحلي نجرّب صغيراً أولاً أي عنصر يُضمَّن، وماذا يحدث للتركيز والإدخال وDPI والسمة، وهل تكوين المضيف مستقر، ولا نعامله من البداية كقارب نجاة.
p0["توقع «لاحقاً نُصلح»"] --> p1["أي عنصر نريد تضمينه"]
p0 --> p2["التركيز والإدخال وDPI والسمة"]
p0 --> p3["هل تكوين المضيف مستقر"]
p1 --> p4["تجربة صغيرة أولاً"]
p2 --> p4
p3 --> p4
الشكل 20: لا نُعامل XAML Islands كقارب نجاة، بل نجرّب ثلاث نقاط بنطاق صغير أولاً.
7. زاوية النظر عندما يكون التطبيق القائم هو الافتراض
هنا الأصل القائم أهم من الجديد.
7.1 إن وُجد WinForms قائم
أولاً نتحقق من هنا قبل القفز فوراً إلى WinUI.
- هل يمكن التقريب إلى .NET الحالي
- هل يلزم التحويل إلى 64bit
- هل يمكن ترتيب async / await ومعالجة الاستثناءات والإعدادات والسجلات
- هل يمكن رفع قابلية الصيانة بتقسيم الشاشات أو التحويل إلى UserControl
- هل يمكن إضافة وظائف Windows اللازمة فقط بـ Windows App SDK
ما يبدو مشكلة WinForms، في الواقع كثيراً ما يكون فقط:
- اختلاط الشاشة والمنطق
- حدود خيوط خشنة
- اكتظاظ مسؤوليات الإعداد / الملف / COM / DB
عندها حتى الانتقال إلى WinUI يُبقي المشكلة وقد تغيّر اسمها فقط.
flowchart TB
accTitle: المشكلة تبقى وقد تغيّر اسمها
accDescr: مخطّط يبيّن أن ما يبدو مشكلة WinForms كثيراً ما يكون اختلاط الشاشة والمنطق وحدود خيوط خشنة واكتظاظ مسؤوليات، وعندها حتى الانتقال إلى WinUI يُبقي المشكلة وقد تغيّر اسمها.
e1["تبدو مشكلة WinForms"] --> e2["في الواقع مشكلة بنية"]
e2 --> e3["اختلاط الشاشة والمنطق"]
e2 --> e4["حدود خيوط خشنة"]
e2 --> e5["اكتظاظ المسؤوليات"]
e4 --> e6["حتى الانتقال إلى WinUI يُبقيها باسم آخر"]
الشكل 21: مشكلة البنية التي تبدو مشكلة واجهة تبقى حتى لو تغيّر الإطار.
7.2 إن وُجد WPF قائم
WPF يسهل الاستفادة من الأصل القائم.
- أصل XAML
- Binding
- Style / Template
- Command
- MVVM
سبب التخلي عن هذه يجب أن يكون واضحاً جداً.
مثلاً،
- نريد تجديد واجهة المنتج بالكامل
- نريد جعل Fluent محوراً
- نقطع وحدة جديدة كمنتج منفصل
- نريد الميل إلى تجربة جديدة كمنتج مخصص لـ Windows
فعندها يصير ذلك سبب النظر في WinUI. لكن «لأن WPF قديم» وحده ضعيف.
7.3 ما يثقل حقاً غالباً خارج الواجهة
في العمل، ما يشق غالباً هذه الناحية على غير المتوقع.
- ActiveX / OCX
- COM interop
- تقارير مخصصة
- الطباعة
- ربط Excel / Office
- DLL أصلي
- التواء 32bit / 64bit
- المثبّت، الأذونات، التحديث، التوقيع
إذا استُخف بهذه، فتجميل الواجهة وحدها لا يخفّف المشروع كله.
لذا في ترحيل تطبيق قائم، الأولى جرد حدود الاعتماد كلها، لا النظر إلى إطار الواجهة وحده.
flowchart TB
accTitle: الجرد حسب حدود الاعتماد
accDescr: مخطّط يبيّن أن ما يثقل في العمل غالباً خارج الواجهة: ActiveX و COM والتقارير والطباعة وDLL الأصلي والمثبّت والتحديث، لذا الجرد حسب حدود الاعتماد أولى من النظر إلى إطار الواجهة وحده.
d1["ActiveX / COM interop"] --> d4["ما يثقل حقاً خارج الواجهة"]
d2["تقارير وطباعة وربط Office"] --> d4
d3["مثبّت وأذونات وتحديث وتوقيع"] --> d4
d4 --> d5["الجرد حسب حدود الاعتماد أولاً"]
d5 -.-> d6["تجميل الواجهة وحدها لا يخفّف"]
الشكل 22: في الترحيل ما يثقل حقاً اعتمادات خارج الواجهة، فالجرد أولاً.
8. خمسة أسئلة ننظر إليها أخيراً عند الحيرة
إن حِرنا في النهاية، نطبّق هذه الأسئلة الخمسة بالترتيب.
8.1 هل الأصل القائم كبير؟
- كبير ← الإبقاء على النَسَب القائم أساساً
- صغير / غير موجود ← إلى اختيار جديد
8.2 هل «تجربة Windows الحديثة» إلزامية في هذا التطبيق؟
- إلزامية ← WinUI قوي
- ليست إلى ذلك الحد ← التأكد مما إذا كان WPF / WinForms يكفي
8.3 هل الشاشة محورها نماذج قياسية، أم تحتاج قدرة تعبير بأسلوب XAML؟
- محورها نماذج قياسية ← WinForms
- الأنماط / القوالب / Binding / MVVM مهمة ← WPF
8.4 ما نريده تجديد شامل للواجهة، أم إضافة وظائف Windows؟
- تجديد شامل للواجهة ← النظر في WinUI
- إضافة وظائف فقط ← النظر أولاً في WPF / WinForms الحالي + Windows App SDK
8.5 هل نستطيع شرح التوزيع / التحديث / التشغيل مسبقاً؟
- لا يزال غائماً ← في WinUI نضيّق packaging / deployment مبكراً
- نريد الركوب بقوة على تشغيل قائم ← غالباً WPF / WinForms أقل احتكاكاً
flowchart TB
accTitle: تدفق الأسئلة الخمسة الأخيرة
accDescr: مخطّط يبيّن تضييق الخيارات بتطبيق أسئلة بالترتيب: هل الأصل القائم كبير، وهل التجربة الحديثة إلزامية، وهل المحور نماذج قياسية أم قدرة تعبير، وهل يمكن شرح التوزيع والتحديث والتشغيل.
f1{"هل الأصل القائم كبير؟"} -->|"كبير"| f2["الإبقاء على النَسَب القائم أساساً"]
f1 -->|"صغير / غير موجود"| f3{"هل التجربة الحديثة إلزامية؟"}
f3 -->|"إلزامية"| f4["WinUI قوي"]
f3 -->|"ليست إلى ذلك الحد"| f5{"هل المحور نماذج قياسية؟"}
f5 -->|"نعم"| f6["WinForms"]
f5 -->|"قدرة التعبير مهمة"| f7["WPF"]
f2 -.-> f8["إن كانت إضافة وظائف فقط ننظر في SDK أولاً"]
f4 -.-> f9["نضيّق packaging والتوزيع مبكراً"]
الشكل 23: عند الحيرة نضيّق بتطبيق الأسئلة بهذا الترتيب: الأصل القائم، التجربة، طبيعة الشاشة.
بهذه الأسئلة الخمسة يمكن التضييق كثيراً. أخيراً بصورة خشنة، الأمر هكذا.
- نماذج داخلية تُبنى بسرعة ← WinForms
- تطبيق أعمال Windows ينمو طويلاً ← WPF
- واجهة منتج Windows حديثة جديدة ← WinUI
- تحديث وظائف Windows فقط مع الاستفادة من الأصل ← الإطار الحالي + Windows App SDK
9. الخلاصة
اختيار WinForms و WPF و WinUI ليس لعبة صفّ الأحدث وأخذ أقصى اليمين.
ما ينبغي النظر إليه أولاً هذه الأربعة.
- أين يوجد الأصل القائم
- هل الشاشة محورها نماذج، أم محورها التعبير
- هل واجهة Windows الحديثة متطلب منتج
- كيف ندير التوزيع / التحديث / التشغيل
إذا اتضحت هذه الأربعة، تُحسم السياسة تقريباً.
flowchart TB
accTitle: الأسئلة الأربعة في الخلاصة
accDescr: مخطّط يبيّن أنه إذا اتضح أين الأصل القائم، وطبيعة الشاشة نماذج أم تعبيراً، وهل الواجهة الحديثة متطلب منتج، وكيف ندير التوزيع والتحديث والتشغيل، تُحسم السياسة تقريباً.
n1["الأصل القائم"] --> n5["تُحسم السياسة تقريباً"]
n2["طبيعة الشاشة"] --> n5
n3["متطلب الواجهة الحديثة"] --> n5
n4["التوزيع والتشغيل"] --> n5
الشكل 24: إذا اتضحت الأسئلة الأربعة، تُحسم سياسة الإطار تقريباً.
- إن كنت تحمل WinForms قائماً كبيراً، فمواصلة WinForms أولاً
- إن كنت تحمل WPF قائماً كبيراً، فمواصلة WPF أولاً
- في الجديد إن كان المحور نماذج قياسية فـ WinForms
- في الجديد إن كان تطبيق أعمال Windows متوسطاً إلى كبير فـ WPF
- في الجديد إن كانت تجربة Windows الحديثة نفسها متطلباً فـ WinUI
- إن أردنا Windows App SDK فقط، فلا نجعل كل شيء WinUI دفعة واحدة
أكثر ما يجب تجنّبه هذه الثلاثة.
- نرميه لأنه قديم
- نختاره لأنه جديد
- نبدأ على فرض أن الأمر سيُصلح في الوسط
سطح مكتب Windows عالم الأصل والتوزيع والتشغيل والاعتمادات فيه أثقل من المظهر. لذا أعمل أن نعطي الأولوية لاختيار أقل احتكاكاً مع الأصل القائم والتوزيع والتشغيل، لا للجدة.
10. روابط مرجعية
-
Microsoft Learn, WinUI 3 - Windows apps / Microsoft Learn, Modernize your desktop apps for Windows ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
Microsoft Learn, What is Windows Presentation Foundation - WPF ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, What is Windows Forms Designer? ↩ ↩2
-
Microsoft Learn, Data binding overview - WPF ↩ ↩2 ↩3
-
Microsoft Learn, Commanding Overview - WPF ↩ ↩2 ↩3
-
Microsoft Learn, Use the Windows App SDK in a WPF app ↩ ↩2 ↩3
-
Microsoft Learn, Use the Windows App SDK in a Windows Forms (WinForms) app ↩ ↩2 ↩3
-
Microsoft Learn, Windows developer FAQ ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9
-
Microsoft Learn, Windows App SDK 1.4 release notes / Microsoft Learn, Windows App SDK ↩ ↩2 ↩3
-
Microsoft Learn, Windows data binding and MVVM ↩
-
Microsoft Learn, Packaging overview - Windows apps / Microsoft Learn, Grant package identity by packaging with external location ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
Microsoft Learn, Quick start: Set up your environment and create a WinUI 3 project ↩
-
Microsoft Learn, Package and deploy Windows apps overview ↩ ↩2
-
Microsoft Learn, What’s new in WPF for .NET 9 ↩
-
Microsoft Learn, What’s new in WinForms for .NET 9 ↩
-
Microsoft Learn, Windows App SDK release channels ↩
مقالات ذات صلة
أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.
CI/CD عمليّ لتطبيقات WinForms / WPF ── أتمتة البناء والتوقيع والتوزيع عبر GitHub Actions
دليل عمليّ لبناء CI/CD لتطبيقات WinForms / WPF عبر GitHub Actions. يشمل YAML الأدنى للبناء والاختبار على windows-latest، وترقيم الإصدار ا...
إقامة تطبيقات Windows في علبة النظام والإشعارات المنبثقة ── مطبات NotifyIcon وكيفية اختيار AppNotification
نرتّب إقامة تطبيقات Windows للأعمال في علبة النظام والإشعارات المنبثقة. نشرح الاستخدام الصحيح لـ NotifyIcon، وإعادة التسجيل عند إعادة تشغ...
ما ينبغي تنظيمه قبل طلب التعهيد أو التطوير التعاقديّ لتطبيق Windows
قبل تكليف جهة خارجية بتطوير تطبيق Windows تعاقديّاً، إليك النقاط التي ينبغي تنظيمها: تعديل البرمجيّات القائمة، وتكامل الأجهزة، وCOM/Activ...
لماذا نستخدم Generic Host و BackgroundService في تطبيق سطح المكتب
تنظيم البدء والمعالجة الدوريّة والإيقاف والسجلات والإعدادات و DI في أدوات Windows والتطبيقات المقيمة باستخدام Generic Host و BackgroundSe...
انتهاء خدمة برامج تشغيل الطابعات في Windows ── كيف تستعد تطبيقات الأعمال لطباعة التقارير والملصقات
تُنهى Microsoft تدريجيّاً خدمة برامج تشغيل الطابعات v3/v4، ومن تمّوز/يوليو 2026 يُفضَّل برنامج تشغيل فئة IPP. نرتّب في جداول قرار ما يختف...
أين يتصل هذا الموضوع
ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.
تطوير تطبيقات ويندوز
اختيار WinForms أو WPF أو WinUI موضوع يتّصل مباشرة بالتطوير الجديد لتطبيقات سطح المكتب على Windows وبسياسة إطالة عمر الأصول القائمة.
الاستشارات التقنية ومراجعة التصميم
مناسب لمرحلة ترتيب أيّ الخيارات أقلّ احتكاكاً، بما يشمل الأصول القائمة وWindows App SDK وتصميم التوزيع وأسلوب عرض واجهة المستخدم وثقافة MVVM.
الأسئلة الشائعة
أسئلة شائعة حول موضوع هذه المقالة.
- ما الفرق بين WinUI 3 و WPF؟
- كلاهما يستخدم XAML، لكن WinUI ليس «مجرد WPF أحدث». يختلف API الأساسي، وعالم العناصر، وتركيبة المشروع، وتفكير التوزيع / packaging، وعلاقة Windows App SDK. WPF إطار UI لتطبيقات أعمال متوسطة إلى كبيرة يملك رسماً متجهاً مستقلاً عن الدقة، وdata binding، وأنماط / قوالب، وأوامر. WinUI إطار UI حديث كجزء من Windows App SDK، يفترض Fluent وDPI عالياً وتجربة Windows الحديثة. اعتباره بديلاً سهلاً عن WPF خطر.
- في التطوير الجديد، أيّها نختار: WinForms أم WPF أم WinUI؟
- ينقسم الأمر حسب طبيعة الشاشة ومتطلبات المنتج. لأداة داخلية صغيرة إلى متوسطة محورها عناصر قياسية ونماذج إدخال وتريد البناء بسرعة، لا يزال WinForms قوياً جداً. لتطبيق أعمال متوسط إلى كبير بعدد شاشات كبير، وتريد استخدام data binding والأنماط والقوالب وMVVM بجدية، غالباً ما يكون WPF الأكثر أماناً. لمنتج جديد مخصص لـ Windows تكون فيه Fluent وتجربة Windows الحديثة مرتبطة مباشرة بقيمة المنتج، يكون WinUI مرشحاً قوياً. إذا كان الأصل القائم كبيراً، ننظر أولاً إلى مواصلة ذلك النَسَب.
- هل WPF و WinForms قديمان وانتهيا؟
- لا تقطعهما بخشونة. WinForms و WPF مستمران في التوثيق ومسارات الترحيل على .NET الحالي، وتعاملهما الوثائق الرسمية كواجهات سطح مكتب Windows حالية. خصوصاً في تطبيقات الأعمال، غالباً ما يكون الأصل القائم وعناصر الطرف الثالث والتقارير والطباعة والربط بالأجهزة وإجراءات التوزيع أثقل من حداثة إطار الواجهة. حتى في الجديد، ليست نادرة المشاهد التي يكون فيها WinForms أو WPF الاختيار الأقل احتكاكاً.
- هل يجب الانتقال إلى WinUI لاستخدام أحدث ميزات Windows؟
- لا. Windows App SDK و WinUI ليسا الشيء نفسه. WinUI هو جزء إطار الواجهة في Windows App SDK. يمكن إضافة Windows App SDK نفسه إلى تطبيقات WPF / WinForms / Win32 القائمة، وقد تُدمَج وظائف مثل App Lifecycle و Windowing و Toast Notifications مع الإبقاء على الواجهة الحالية. أي أن هناك مساراً لتحديث ميزات Windows اللازمة مع الإبقاء على WPF / WinForms، والترحيل الشامل للواجهة ليس إلزامياً.
الملف الشخصي للمؤلف
صفحة الملف الشخصي لمؤلف المقالة.
غو كومورا
مؤسّس شركة كومورا سوفت ذ.م.م.
يركّز على تطوير برامج ويندوز، والاستشارات التقنية، والتحقيق في الأخطاء، ويتميّز في المشاريع التي تبقى فيها الأصول القديمة ناشطة، وفي تشخيص الأعطال التي يصعب تحديد سببها.