طريقة عالمية لتخصيص مظهر تطبيق WinForms (باستخدام مثال FAQ.Net)

مقدمة


بعد نشر المقالة الأولى حول تطبيق FAQ.Net الخاص بي (برنامج Windows note) ، ظهر المستخدمون الأوائل الذين يرغبون في تطوير برنامج الملاحظات الخاص بهم.

لزيادة اهتمام المستخدمين ، نشأت فكرة لزيادة جاذبيتها من خلال ضبط اللون والخط.

متطلبات تخصيص مظهر التطبيق


  1. تخزين وتحميل خصائص المكونات الفردية في ملف XML
  2. يجب أن يكون لدى المستخدم أداة بسيطة لتخصيص المظهر
  3. يجب توسيع قائمة المكونات المخصصة بكل بساطة (في سطر واحد من التعليمات البرمجية)
  4. عند تغيير قيمة الخاصية ، يجب على المستخدم أن يرى على الفور التغييرات في النموذج
  5. يجب أن يكون هناك زر إلغاء يسمح لك بالعودة إلى كل التغييرات

نتيجة العمل


نافذة المظهر:



قبل وبعد إعدادات المظهر:



لحل المشكلة من الضروري


  1. استخدم مكون PropertyGridEx لعرض وتغيير خصائص المكون
  2. إنشاء فئة CustomDesignControl لراحة تخزين الخصائص في XML
  3. إنشاء نموذج MainForm ، والذي سنقوم بتغيير المظهر
  4. إنشاء نموذج AppSettingsForm ، حيث سنقوم بتخصيص مظهر MainForm
  5. إنشاء فئة SettingsXml لسهولة العمل مع XML

وظيفة التراجع عن التغييرات في المظهر


لتنفيذ إلغاء التغييرات في المظهر (الفقرة 5 من المتطلبات) ، قررت أن أجد طريقة عالمية لاستنساخ خصائص المكونات التي سيتم إنشاؤها في الذاكرة واستبدال المكونات المعروضة.

كائنات الاستنساخ:

public static class ControlExtensions { public static T Clone<T>(T controlToClone) where T : Control { PropertyInfo[] controlProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); T instance = Activator.CreateInstance<T>(); RichTextBox rtb = new RichTextBox(); foreach (PropertyInfo propInfo in controlProperties) { if (propInfo.Name == "Parent") continue; if (propInfo.CanWrite) { if (propInfo.Name != "WindowTarget") { propInfo.SetValue(instance, propInfo.GetValue(controlToClone, null), null); } } } return instance; } 

لقد قمت بنسخ الرمز ، وإزالة الخصائص غير الضرورية التي لا تحتاج إلى حفظ ، وترك الألوان والخط.
بعد التحقق من الكود ، تم الكشف عن أوجه القصور في هذه الطريقة على الفور:

  1. يتم استخدام صب أي عنصر تحكم إلى فئة التحكم ، مما يعني أنه يمكن فقد نصف الخصائص (على سبيل المثال ، يتم توريث مكون DataGridView من فئة التحكم ، ولكن لديه مجموعة خصائص إضافية خاصة به)
  2. عند استنساخ مكون ، لا يتم استنساخ بعض الخصائص (على سبيل المثال: لون الخط داخل خلية DataGridView) ، ولكن إنشاء روابط للمكون المستنسخ (ربما يكون هذا بسبب استخدام الخاصية مع خصائصها الداخلية وتحتاج إلى معالجتها بطريقة مختلفة بطريقة ما).

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

 DataGridView dgvClone = new DataGridView(); 

ولكن دون جدوى ، لم يتمكن المكون من التراجع عن التغييرات.

حاولت بعد ذلك إنشاء الخاصية نفسها باستخدام عامل التشغيل الجديد وتعيين القيمة إليها باستخدام طريقة SetValue:

 propInfo.SetValue(_controls[i], propInfo.GetValue(_controlsBeforeChange[i], null), null); 

وهذه الطريقة لم تعطي نتيجة. عندما تتغير قيمة الخاصية في مكون واحد ، يتم تحديثها تلقائيًا في المكون الذي تم استنساخه.

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

تطبيق مثال مع تخصيص المظهر


فقط في حالة ، لقد أعددت رمزًا جاهزًا يمكن للجميع من خلاله فحص وظيفة إلغاء التغييرات في المظهر وربما تحسينها دون إعادة تشغيل التطبيق وإخبارنا بالمشكلة في التعليقات.
من الضروري التأكد من أنه عند النقر فوق الزر "AutoTest" ، يكون للمكون DataGridView خلفية رمادية ويكون خط الخلايا صغيرًا.



تنزيل تطبيق Windows FAQ.Net (مجانًا):

(x64) yadi.sk/d/sq3g4NOD3Zt7ZY
(x86) yadi.sk/d/NKXeyUW33t8PQ

مجموعة VK
شفرة المصدر FAQ.Net

استنتاج


آمل أنه في العديد من تطبيقات WinForms ، وبفضل هذه المقالة ، ستتاح للمستخدم النهائي الفرصة لتخصيص الواجهة حسب ذوقها ولونها.

Source: https://habr.com/ru/post/ar474104/


All Articles