이 프로젝트는 .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 호출 할 때 Dark Mode 및 High Contrast와 관련하여 운영 체제의 설정을 존중합니다. 추가 선택 기준을 추가하려고하거나 사용자 에게이 선택을 무시할 수있는 옵션을 제공하려면 쉽게 수행 할 수 있습니다. IThemeRegistry.GetTheme() 의 기본 설정에 의존하는 대신 CurrentThemeSelector 제공하여 원하는 테마로 IThemeRegistry.Current 설정할 수 있습니다.
IThemeRegistry registry = ThemeRegistryHolder . GetBuilder ( )
. WithCurrentThemeSelector ( registry => registry . GetTheme ( ) )
. Build ( ) ;
var selectedTheme = registry . CurrentTheme ;상자 밖에 커스텀 테마를 추가 할 수있는 두 가지 방법이 있습니다.
.theme.json 작업 dir의 themes 디렉토리에 저장된 파일이있는 파일입니다.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 스키마를 여기에서 확인하십시오.
이러한 두 가지 방법이 충분히 유연하지 않은 경우 스스로 테마를 구현하고 사용자 정의 테마 소스를 사용하여 등록 할 수 있습니다 (아래 참조) : 기본 색상을 구현하고 선택적으로 확장 된 색상을 대체하는 데 필요한 방법은 기본 AbstractTheme 에서 컨트롤이 수행됩니다.
더 고급적인 방법은 ITheme 인터페이스를 구현하는 것입니다. 이것은 테마 기능과 같은 기본 인프라 만 지원하지만 스타일은 완전히 손에 있습니다.
뷰는 IThemeLookup (아래 참조)을 구현하거나 빌더에 직접 추가하여 추가 할 수 있습니다.
ThemeRegistryHolder . GetBuilder ( )
. WithThemes ( )
. AddDefaultThemes ( )
. AddTheme ( new MySuperDarkTheme ( ) )
. FinishThemeList ( )
. Build ( ) ; 파일 및 리소스 외에 다른 테마 소스를 추가하려면 (예 : Custom 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 Control Library를 사용하도록 강요하고 싶지 않기 때문에 현재 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 ( ) ;참고 : 현재 직접 등록 된 유형 만 지원합니다. 서브 클래스는 자동으로 스타일을 지정하지 않습니다!
자세한 내용은 기고 안내서를 참조하십시오.