该项目在.NET Winforms应用程序中增加了对主题的支持。该项目支持开箱即用的和自定义主题,并使用我们的Winforms-stylable-Controls项目来样式的控制风格支持。
首先,安装报告机器工具:
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 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.Current检索当前主题和IThemeRegistry.OnThemeChanged ,以通知更改:
var mytheme = ThemeRegistryHolder . ThemeRegistry . Current ;
ThemeRegistryHolder . ThemeRegistry . OnThemeChanged += ( sender , args ) =>
{
//logic to handle theme change here
} ;默认情况下,我们的图书馆将在致电GetTheme时尊重操作系统的设置以及高度对比度。如果要添加其他选择标准,或者想为用户提供一个选择以覆盖此选择的选项,则可以轻松执行此操作。您可以通过提供CurrentThemeSelector来设置IThemeRegistry.Current IThemeRegistry.GetTheme()中的默认设置。
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-Sypy-Sylable-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 ( ) ;注意:当前,我们仅支持直接注册的类型。子类不会自动设计!
请查看贡献指南以获取更多信息。