يضيف هذا المشروع دعمًا للموضوعات في تطبيقات .NET Winforms. يدعم هذا المشروع كلاً من السمات المخصصة والمخصصة ويستخدم مشروع WinForms-stylable-controls إلى أدوات التحكم في الأناقة التي تفتقر إلى دعم الأسلوب.
أولاً ، قم بتثبيت أداة ReportGenerator:
dotnet tool install -g dotnet-reportgenerator-globaltool
بعد ذلك ، قم ببناء نسخة تصحيح من المشروع:
dotnet build WinFormsThemes/WinFormsThemes.sln -c Debug
يمكن بعد ذلك إنشاء تقرير تغطية الاختبار باستخدام:
rmdir /s /q WinFormsThemesTestProjectTestResults
dotnet test WinFormsThemes/TestProject --no-build --verbosity normal --collect:"XPlat Code Coverage"
reportgenerator -reports:WinFormsThemesTestProjectTestResults*coverage.cobertura.xml -targetdir:WinFormsThemesTestProjectTestResultshtml -reporttypes:Html -sourcedirs:WinFormsThemesWinFormsThemes
start "" WinFormsThemesTestProjectTestResultshtmlindex.html
نستخدم stryker.net لاختبار الطفرة. لتشغيل اختبارات الطفرة ، استخدم:
dotnet tool restore
dotnet stryker
مهم: لا تبدأ Stryker في دليل المشروع - تحتاج إلى بدء تشغيله في الحل ، وإلا فلن يتم العثور على التكوين!
لاستخدام هذا المشروع ، تحتاج إلى إضافة مرجع إلى حزمة nuget الخاصة بنا ( dotnet add package AssortedDevelopment.WinFormsThemes ) أولاً.
ملاحظة: حاليًا ، يتطلب هذا المشروع .NET 6.0 أو أعلى.
بعد ذلك ، تحتاج إلى تكوين السمات:
var registry = ThemeRegistryHolder . GetBuilder ( ) . Build ( ) ;
var theme = registry . ThemeRegistry . GetTheme ( ) ; يمكن وضع هذا ، على سبيل المثال ، في Program.cs
في النهاية ، تحتاج إلى توفير السمة لجميع النماذج ليتم موضوعها وإضافة سطر واحد في حدث Load :
theme . Apply ( this ) ;سيطبق هذا هذا الموضوع على النموذج المحدد وجميع الأطفال.
بالطبع ، يمكنك تمديد هذه المكتبة وتخصيص المناولة لتناسب احتياجاتك. فيما يلي بعض الأمثلة:
إذا كنت ترغب في تصحيح مشكلة في هذه المكتبة ، فيمكنك تمكين تسجيل الدخول في IThemeRegistryBuilder :
ThemeRegistryHolder . GetBuilder ( ) . SetLoggerFactory ( LoggerFactory ) . Build ( ) ; سيؤدي ذلك إلى تسجيل جميع تصرفات المكتبة إلى ILoggerFactory المعطى.
ملاحظة: لن تتأثر أي مكالمات قبل استدعاء SetLoggerFactory ، لذلك ننصح بالاتصال SetLoggerFactory في أقرب وقت ممكن.
عندما لا يكون لديك حقن تبعية متاح في مشروعك ، فإننا نقدم الأدوات المساعدة لجعل كل من IThemeRegistry و ITheme متاحًا عالميًا:
IThemeRegistry for IThemeRegistry ، نحن نقدم فئة ThemeRegistryHolder التي يمكن استخدامها لتخزين السجل واستردادها لاحقًا: ThemeRegistryHolder . ThemeRegistry = ThemeRegistryHolder . GetBuilder ( ) . Build ( ) ; بعد ذلك ، يمكنك استرداد السجل من أي مكان في التطبيق الخاص بك باستخدام: var registry = ThemeRegistryHolder.ThemeRegistry;
ITheme لـ ITheme ، توفر IThemeRegistry خاصية Current يمكن استخدامها لاسترداد السمة الحالية. لكي يعمل هذا ، تحتاج إلى تكوين محدد يحدد السمة الحالية: private ITheme SelectCurrentTheme ( IThemeRegistry registry )
{
//logic to select theme here
}
.. .
ThemeRegistryHolder . ThemeRegistry = ThemeRegistryHolder . GetBuilder ( ) . WithCurrentThemeSelector ( SelectCurrentTheme ) . Build ( ) ; يمكّنك ذلك من IThemeRegistry.OnThemeChanged IThemeRegistry.Current .
var mytheme = ThemeRegistryHolder . ThemeRegistry . Current ;
ThemeRegistryHolder . ThemeRegistry . OnThemeChanged += ( sender , args ) =>
{
//logic to handle theme change here
} ; بشكل افتراضي ، ستكرم مكتبتنا إعدادات نظام التشغيل فيما يتعلق بالوضع المظلم والتباين العالي عند استدعاء GetTheme . إذا كنت ترغب في إضافة معايير اختيار إضافية أو تريد منح المستخدم خيارًا لتجاوز هذا التحديد ، يمكنك القيام بذلك بسهولة. بدلاً من الاعتماد على الإعدادات الافتراضية في IThemeRegistry.GetTheme() يمكنك تعيين IThemeRegistry.Current CurrentThemeSelector
IThemeRegistry registry = ThemeRegistryHolder . GetBuilder ( )
. WithCurrentThemeSelector ( registry => registry . GetTheme ( ) )
. Build ( ) ;
var selectedTheme = registry . CurrentTheme ;خارج الصندوق ، هناك طريقتان يمكنك إضافة سمات مخصصة:
themes .theme.jsonCONFIG_THEMING_THEME_تستخدم كلتا الطريقتين نفس تنسيق JSON لتعريف السمة (يحدد الإصدار تنسيق الملف). مثال بسيط على ذلك يمكن أن يكون:
{
"name" : " theme-name " ,
"capabilities" : [ " DarkMode " , " HighContrast " ],
"version" : 3 ,
"variables" : {
"backColor" : " #082a56 " ,
"foreColor" : " #082a57 "
},
"colors" : {
"backColor" : " backColor " ,
"foreColor" : " foreColor " ,
"controls" : {
"backColor" : " backColor " ,
"foreColor" : " foreColor "
}
}
}للحصول على القائمة الكاملة للإعدادات المتاحة ، يرجى التحقق من مخطط JSON الخاص بنا هنا.
إذا لم تكن هاتان الطريقين مرنين بما فيه الكفاية ، فيمكنك تنفيذ سمة بنفسك وتسجيلها باستخدام مصدر مخصص للموضوع (انظر أدناه): الطريقة المفضلة هي أن فئة الفرعية AbstractTheme حيث تحتاج فقط إلى تنفيذ الألوان الأساسية وتجاوز الألوان الموسعة اختياريًا - يتم تصميم عناصر التحكم بواسطة الفئة الأساسية.
الطريقة الأكثر تقدما هي تنفيذ واجهة ITheme . هذا يدعم فقط البنية التحتية الأساسية مثل إمكانيات الموضوع ولكن التصميم في يديك تمامًا.
يمكن إضافة طرق العرض إما عن طريق تنفيذ IThemeLookup (انظر أدناه) أو عن طريق إضافتها مباشرة إلى المنشئ:
ThemeRegistryHolder . GetBuilder ( )
. WithThemes ( )
. AddDefaultThemes ( )
. AddTheme ( new MySuperDarkTheme ( ) )
. FinishThemeList ( )
. Build ( ) ; إذا كنت ترغب في إضافة مصدر آخر للموارد إلى جانب الملفات والموارد (على سبيل المثال ، عند تطبيق تطبيقات ITheme أو AbstractTheme مخصصة) أو تريد فقط تغيير مسار المجلد ، يمكنك إضافة تطبيق IThemeLookup المخصص الذي يتولى البحث عن الموضوعات المتاحة:
internal class MyThemeLookup : IThemeLookup
{
public int Order => 999 ; //highest order wins when 2 lookups return the same theme name
public List < ITheme > Lookup ( )
{
List < ITheme > results = new List < ITheme > ( ) ;
//implement search for themes here
return results ;
}
}
}بعد ذلك ، تحتاج إلى تسجيل هذا الفصل في المنشئ:
ThemeRegistryHolder . GetBuilder ( )
. WithThemes ( )
. AddDefaultThemes ( )
. WithLookup ( )
. FinishThemeList ( )
. Build ( ) ;نظرًا لأننا لا نريد إجبارك على استخدام مكتبة التحكم في WinForms محددة ، فإننا ندعم حاليًا فقط تصميم عناصر التحكم القياسية وعناصر التحكم من مشروع WinForms-Stylable-Controls. كما نفهم أنك قد ترغب أيضًا في تصميم عناصر تحكم أخرى ، فإننا ندعم إضافة مكونات إضافية متخصصة للتعامل مع تصميم نوع معين من التحكم. للقيام بذلك ، تحتاج إلى تنفيذ ``:
internal class MyCustomControlThemePlugin : AbstractThemePlugin < MyCustomControl >
{
protected override void ApplyPlugin ( MyCustomControl mcc , AbstractTheme theme )
{
//style control based on the colors available in the Theme
}
}أخيرًا ، تحتاج فقط إلى تسجيله للنوع الصحيح:
ThemeRegistryHolder . GetBuilder ( )
. AddThemePlugin ( new MyCustomControlThemePlugin ( ) )
. Build ( ) ;ملاحظة: حاليًا ، ندعم فقط الأنواع المسجلة مباشرة. لن يتم تصميم الفئات الفرعية تلقائيًا!
يرجى الاطلاع على دليل المساهمة لمزيد من المعلومات.