โครงการนี้เพิ่มการสนับสนุนสำหรับธีมในแอปพลิเคชัน. 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 ในไดเรกทอรีโครงการ - คุณต้องเริ่มต้นในการแก้ปัญหา DIR มิฉะนั้นจะไม่พบการกำหนดค่า!
ในการใช้โครงการนี้คุณจะต้องเพิ่มการอ้างอิงไปยังแพ็คเกจ 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 สำหรับ 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.Current เพื่อดึงชุดรูปแบบปัจจุบันและ IThemeRegistry.OnThemeChanged เพื่อรับการแจ้งเตือนการเปลี่ยนแปลง:
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 ;นอกกรอบมี 2 วิธีที่คุณสามารถเพิ่มธีมที่กำหนดเอง:
.theme.json เก็บไว้ในไดเรกทอรี themes ของ DIR ที่ใช้งานได้CONFIG_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 ของเราที่นี่
หาก 2 วิธีเหล่านั้นไม่ยืดหยุ่นเพียงพอคุณสามารถใช้ธีมด้วยตัวเองและลงทะเบียนโดยใช้แหล่งธีมที่กำหนดเอง (ดูด้านล่าง): วิธีที่ต้องการคือการย่อยคลาส 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 ( ) ;หมายเหตุ: ปัจจุบันเราสนับสนุนเฉพาะประเภทที่ลงทะเบียนโดยตรง คลาสย่อยจะไม่ได้รับการออกแบบโดยอัตโนมัติ!
โปรดดูคู่มือการสนับสนุนสำหรับข้อมูลเพิ่มเติม