Ce projet ajoute une prise en charge des thèmes dans les applications .NET WinForms. Ce projet prend en charge à la fois des thèmes prêts à l'emploi et des thèmes personnalisés et utilise notre projet WinForms-Sylable-Controls pour styliser des contrôles qui manquent de support de style.
Installez d'abord l'outil ReportGenerator:
dotnet tool install -g dotnet-reportgenerator-globaltool
Ensuite, créez une version de débogage du projet:
dotnet build WinFormsThemes/WinFormsThemes.sln -c Debug
Le rapport de couverture de test peut ensuite être créé en utilisant:
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
Nous utilisons Stryker.net pour les tests de mutation. Pour exécuter les tests de mutation, utilisez:
dotnet tool restore
dotnet stryker
IMPORTANT: Ne démarrez pas Stryker dans le répertoire du projet - vous devez le démarrer dans le Dir de solution, sinon la configuration ne sera pas trouvée!
Pour utiliser ce projet, vous devez d'abord ajouter une référence à notre package NuGet ( dotnet add package AssortedDevelopment.WinFormsThemes ).
Remarque: Actuellement, ce projet nécessite .NET 6.0 ou plus.
Ensuite, vous devez configurer les thèmes:
var registry = ThemeRegistryHolder . GetBuilder ( ) . Build ( ) ;
var theme = registry . ThemeRegistry . GetTheme ( ) ; Cela peut, par exemple, être placé dans le Program.cs de votre application et utilise les paramètres par défaut pour rechercher les thèmes, renvoyer le registre et utiliser son thème standard.
Enfin, vous devez fournir le thème à toutes les formes pour être à thème et ajouter une seule ligne dans l'événement Load :
theme . Apply ( this ) ;Cela appliquera ce thème sur le formulaire donné et tous les enfants.
Bien sûr, vous pouvez prolonger cette bibliothèque et personnaliser la manipulation pour répondre à vos besoins. Voici quelques exemples:
Si vous souhaitez déboguer un problème avec cette bibliothèque, vous pouvez activer la connexion dans le IThemeRegistryBuilder :
ThemeRegistryHolder . GetBuilder ( ) . SetLoggerFactory ( LoggerFactory ) . Build ( ) ; Cela enregistrera toutes les actions de la bibliothèque à l' ILoggerFactory donné.
Remarque: tous les appels avant d'appeler SetLoggerFactory ne seront pas affectés, nous vous conseillons donc d'appeler SetLoggerFactory le plus tôt possible.
Lorsque vous n'avez pas d'injection de dépendances disponibles dans votre projet, nous fournissons des services publics pour rendre à la fois IThemeRegistry et ITheme à l'échelle mondiale:
IThemeRegistry Pour l' IThemeRegistry , nous fournissons la classe ThemeRegistryHolder qui peut être utilisée pour stocker le registre et la récupérer plus tard: ThemeRegistryHolder . ThemeRegistry = ThemeRegistryHolder . GetBuilder ( ) . Build ( ) ; Après cela, vous pouvez récupérer le registre de n'importe où dans votre application en utilisant: var registry = ThemeRegistryHolder.ThemeRegistry;
ITheme pour l' ITheme , l' IThemeRegistry fournit une propriété Current qui peut être utilisée pour récupérer le thème actuel. Pour que cela fonctionne cependant, vous devez configurer un sélecteur qui définit le thème actuel: private ITheme SelectCurrentTheme ( IThemeRegistry registry )
{
//logic to select theme here
}
.. .
ThemeRegistryHolder . ThemeRegistry = ThemeRegistryHolder . GetBuilder ( ) . WithCurrentThemeSelector ( SelectCurrentTheme ) . Build ( ) ; Cela vous permet d'utiliser IThemeRegistry.Current de récupérer le thème actuel et IThemeRegistry.OnThemeChanged pour être informé des modifications:
var mytheme = ThemeRegistryHolder . ThemeRegistry . Current ;
ThemeRegistryHolder . ThemeRegistry . OnThemeChanged += ( sender , args ) =>
{
//logic to handle theme change here
} ; Par défaut, notre bibliothèque honorera les paramètres du système d'exploitation en ce qui concerne le mode sombre et le contraste élevé lors de l'appel GetTheme . Si vous souhaitez ajouter des critères de sélection supplémentaires ou si vous souhaitez donner à l'utilisateur une option pour remplacer cette sélection, vous pouvez le faire facilement. Au lieu de s'appuyer sur les paramètres par défaut dans IThemeRegistry.GetTheme() vous pouvez définir IThemeRegistry.Current CurrentThemeSelector
IThemeRegistry registry = ThemeRegistryHolder . GetBuilder ( )
. WithCurrentThemeSelector ( registry => registry . GetTheme ( ) )
. Build ( ) ;
var selectedTheme = registry . CurrentTheme ;Hors de la boîte, il existe 2 façons d'ajouter des thèmes personnalisés:
.theme.json stocké dans un répertoire themes du Dir de travail.CONFIG_THEMING_THEME_Les deux façons utilisent le même format JSON pour la définition du thème (la version définit le format du fichier). Un exemple simple de cela pourrait être:
{
"name" : " theme-name " ,
"capabilities" : [ " DarkMode " , " HighContrast " ],
"version" : 3 ,
"variables" : {
"backColor" : " #082a56 " ,
"foreColor" : " #082a57 "
},
"colors" : {
"backColor" : " backColor " ,
"foreColor" : " foreColor " ,
"controls" : {
"backColor" : " backColor " ,
"foreColor" : " foreColor "
}
}
}Pour la liste complète des paramètres disponibles, veuillez consulter notre schéma JSON ici.
Si ces 2 façons ne sont pas suffisamment flexibles, vous pouvez implémenter un thème par vous-même et l'enregistrer à l'aide d'une source de thème personnalisée (voir ci-dessous): La manière préférée est de sous-classer AbstractTheme car vous avez juste besoin d'implémenter les couleurs de base et de remplacer éventuellement les couleurs étendues - le style des commandes est effectué par la classe de base.
La manière la plus avancée consiste à implémenter l'interface ITheme . Cela ne prend en charge que l'infrastructure de base comme les capacités de thème, mais le style est complètement entre vos mains.
Les vues peuvent être ajoutées en implémentant un IThemeLookup (voir ci-dessous) ou en l'ajoutant directement au constructeur:
ThemeRegistryHolder . GetBuilder ( )
. WithThemes ( )
. AddDefaultThemes ( )
. AddTheme ( new MySuperDarkTheme ( ) )
. FinishThemeList ( )
. Build ( ) ; Si vous souhaitez ajouter une autre source de thème en plus de fichiers et de ressources (par exemple, lorsque vous implémentez les implémentations ITheme ou AbstractTheme ) ou si vous souhaitez simplement modifier le chemin du dossier, vous pouvez ajouter une implémentation de cistrie IThemeLookup qui gère la recherche pour les thèmes disponibles:
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 ;
}
}
}Après cela, vous devez enregistrer cette classe dans le constructeur:
ThemeRegistryHolder . GetBuilder ( )
. WithThemes ( )
. AddDefaultThemes ( )
. WithLookup ( )
. FinishThemeList ( )
. Build ( ) ;Comme nous ne voulons pas vous forcer à utiliser une bibliothèque de contrôle WinForms spécifique, nous ne prenons actuellement en charge que le style des contrôles et des contrôles standard de notre projet WinForms-Sylable-Controls. Si nous le comprenons, vous voudrez peut-être également styliser d'autres contrôles, nous prenons en charge l'ajout de plugins spécialisés pour gérer le style d'un type de contrôle spécifique. Pour ce faire, vous devez implémenter ``:
internal class MyCustomControlThemePlugin : AbstractThemePlugin < MyCustomControl >
{
protected override void ApplyPlugin ( MyCustomControl mcc , AbstractTheme theme )
{
//style control based on the colors available in the Theme
}
}Enfin, il vous suffit de l'enregistrer pour le bon type:
ThemeRegistryHolder . GetBuilder ( )
. AddThemePlugin ( new MyCustomControlThemePlugin ( ) )
. Build ( ) ;Remarque: Actuellement, nous prenons uniquement des types directement enregistrés. Les sous-classes ne seront pas stylisées automatiquement!
Veuillez consulter le guide contributif pour plus d'informations.