Salut tout le monde,
Dans le cadre de mes tutoriels sur la création d'un launcher Minecraft, je vais vous apprendre à créer une interface propre et acceptable pour votre launcher.
La particularité ici est que je vais travailler en WPF et non en WinForms , qui de toute façon a été abandonné il y a belle lurette.
Pour information, il est tout à fait aisé de passer de WinForms à WPF , c'est simplement une question d'habitude, et vous trouverez ça génial (c'est un peu comme passer d'un texture pack *16 à un *64 avec shaders).
Je vous invite donc à créer un nouveau projet WPF, si vous n'en avez pas déjà un.
Je détaillerai au possible les étapes.
I . Conseils avant de commencer
Avant de commencer quoi que ce soit, je vais vous donner quelques exemples en image de ce qu'il ne faut pas faire .
1 . Évitez le trop-plein de couleurs
Les couleurs, c'est quelque chose de très important , que ce soit dans la création d'un logiciel ou d'une image.
S'il y a quelque chose que tout le monde aime, même sans s'en rendre compte, c'est l'uniformité des couleurs .
Si votre lanceur contient des couleurs trop flashy , ce sera désagréable de le regarder ; hors, ce n'est pas le but.
Pour cela, optez pour une combinaison de couleurs ayant du sens et se mariant bien.
Figure 1 - Exemple de couleurs mal gérées
Si j'avais un conseil à vous donner, ce serait d'adopter le style Material UI de Google .
En effet, les couleurs conseillées dans la documentation de cette charte graphique sont étudiées pour correspondre entre elles, et sont par ce fait très agréable à l’œil.
Pour ceux qui lisent l'anglais et sont intéressés par le Material Design , je vous invite à lire cette page .
Les autres, je vous invite à mettre cette page en favoris.
2 . Les autres détails
Les textes en gras
Quelque chose d’extrêmement désagréable à voir sur un formulaire quelconque, que ce soit un lanceur Minecraft ou autre, est un texte en gras mal géré. Si vous comptez mettre quelque chose en évidence, utilisez des polices comme Roboto Medium , mais ne mettez pas du gras, car les polices rendent souvent très mal sur un formulaire.
Les fautes d’orthographe
Une faute de frappe c’est vite arrivé, mais si vous n’êtes pas capables d’aligner 10 mots sans faire une faute d’orthographe, utilisez un p*tain de correcteur orthographique. Rien de plus désagréable que de lire un texte rempli de fautes, et je ne suis pas le seul de cet avis. De plus, un rendu sans faute rendra votre lanceur plus professionnel.
Les mauvais alignements
Quand vous alignez des contrôles (que nous verrons plus tard) tels que des étiquettes (labels ), boutons, ou autres éléments graphiques, veillez à ce qu’ils soient alignés (vous pouvez vous aider des valeurs numériques des propriétés Size et Location , de la propriété Dock , et de la barre d'outils Disposition )
Évitez les ombres et le biseautage
Hormis sur les cadres (panels ), les ombres sont à proscrire. De même, le biseautage dans un nom de serveur écrit à la va-vite sur une version tout à fait légale de Photoshop.
Ce sont notamment des points clés de la charte graphique Material UI de Google.
II . L'apparence principale
1 . L'image de fond
Le fond est quelque chose d'assez important dans une fenêtre, puisque c'est la chose que l'on remarque en premier, du moins la plupart du temps, lorsqu'aucun autre élément n'est tape-à-l’œil.
J'ai personnellement choisi une image peu originale, mais ayant l'avantage d'être à la fois jolie et polyvalente .
Figure 2 - L'image de fond que je vais utiliser
Vous pouvez faire Clic droit › Afficher › Enregistrer l'image sous... pour la télécharger
Le WPF ayant ses avantages, voici le code XAML actuel (rien de bien folichon pour le moment) :
Code (xml):
<Window x:Name ="Lanceur" x:Class ="Graphical_Launcher.MainWindow"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local ="clr-namespace:Graphical_Launcher"
mc:Ignorable ="d"
Title ="Lanceur" Height ="600" Width ="1000" WindowStyle ="None" ResizeMode ="NoResize" >
<Window.Background>
<ImageBrush ImageSource ="/Graphical Launcher;component/Resources/background.png" Stretch ="UniformToFill" />
</Window.Background>
<Grid>
</Grid>
</Window>
Vous aurez remarqué le passage de la propriété WindowStyle à None pour enlever les contours, ainsi que la modification du titre , de la largeur et de la hauteur .
Attention › Si vous lancez maintenant, vous aurez une erreur à cause de l'image de fond. Pour régler ceci, allez dans les propriétés de votre image (cliquez sur background.png dans Ressources ) et mettez la propriété Action de génération à Contenu et sélectionnez Toujours copier pour Copier dans le répertoire .
Cliquez pour agrandir...
Figure 3 - Propriétés de l'image de fond
2 . Les bordures
Nous allons maintenant placer des bordures, afin de rendre le tout plus esthétique.
Créez un contrôle Border à l'intérieur du Grid , avec les propriétés BorderBrush à #99000000 et BorderThickness à 2 .
Pour ceux ayant travaillé en WinForms, vous noterez la simplicité acquise avec WPF pour créer des bordures. :)
Code (xml):
<Border x:Name ="WindowBorders" BorderBrush ="#99000000" BorderThickness ="2" />
3 . La boîte de contrôle personnalisée
Nous avons enlevé les contours, et maintenant le seul moyen de fermer la fenêtre est un bon vieux Alt + F4 , ou un stop violent à partir de Visual Studio.
Nous allons donc créer notre boîte de contrôle.
a . Un rectangle pour le fond
Créez un rectangle de hauteur 38 pixels et de transparence 60% . Il sera utilisé pour le fond de la boîte de contrôle.
Voici son code XAML :
Code (xml):
<Rectangle x:Name ="ControlBox" Fill ="#99000000" Height ="38" Margin ="2,2,2,0" VerticalAlignment ="Top" />
b . Une étiquette pour les boutons
Nous allons commencer par créer un style, puisqu'il est inutile de réécrire le même code pour deux boutons.
Ce style devra comporter les propriétés communes aux deux boutons : Background et BorderBrush à Transparent , FontFamily à /Graphical Launcher;component/Resources/#Material Icons , HorizontalAlignment et VerticalAlignment à Right et Top , HorizontalContentAlignment et VerticalContentAlignment à Center , Height et Width à 40 , TextHintingMode à Animated , FontSize à 22.5 , Cursor à Hand , et Foreground à #FFBDBDBD (le blanc pur, c'est trop clair).
Ce style devra être entre les balises <Windows.Resources> , devra cibler les Labels et porter un nom explicitant son but .
Voici le code XAML :
Code (xml):
<Style x:Key ="ControlBoxLabel" TargetType ="Label" >
<Setter Property ="Background" Value ="Transparent" />
<Setter Property ="BorderBrush" Value ="Transparent" />
<Setter Property ="FontFamily" Value ="/Graphical Launcher;component/Resources/#Material Icons" />
<Setter Property ="HorizontalAlignment" Value ="Right" />
<Setter Property ="VerticalAlignment" Value ="Top" />
<Setter Property ="HorizontalContentAlignment" Value ="Center" />
<Setter Property ="VerticalContentAlignment" Value ="Center" />
<Setter Property ="Height" Value ="38" />
<Setter Property ="Width" Value ="38" />
<Setter Property ="TextOptions.TextHintingMode" Value ="Animated" />
<Setter Property ="FontSize" Value ="22.667" />
<Setter Property ="Foreground" Value ="#FFBDBDBD" />
<Setter Property ="Cursor" Value ="Hand" />
</Style>
Vous pouvez maintenant créez vos deux étiquettes, avec comme nom LBL_CLOSE et LBL_REDUCE , et les propriétés Content respectivement à &xe5cd; , et  , ainsi que la propriété Style à {StaticResource ControlBoxLabel} où ControlBoxLabel est le nom de votre style .
Il faut aussi déplacer l'étiquette de réduction de 40 pixels à gauche , sa propriété Margin doit donc être mise à "0,0,40,0 ".
Nous avons nos deux boutons de fermeture et réduction ; il reste maintenant à régler l'erreur que vous devez avoir à cause de la police d'écriture.
c . Police d'écriture personnalisée
Afin de rendre les étiquettes jolies, je vous invite à utiliser la police d'écriture Material Icons , celle que nous avons mis en lien dans le style, sans l'avoir importée.
Téléchargez-la et importez-la dans votre projet ; et mettez-y les même propriétés que pour background.png , sinon votre application va planter au démarrage.
J'en profite pour vous faire télécharger la police Roboto , que nous allons utiliser aussi.
Figure 4 - Téléchargement de la police Roboto
d . L'icône et le titre
Il vous faut maintenant choisir une icône. À ce point, vous avez deux options :
1. Vous avez déjà une d'icône
Vous pouvez le convertir si ce n’est déjà fait sur le site ConvertIco.
Attention › Un logo de taille 32 × 32 pixels est très fortement conseillé, si vous réduisez votre logo de 1000 × 1000 à 32 × 32 , il va être pixelisé et ne rendra pas bien.
Évitez aussi les ombres , le biseautage , tout ce qui peut faire du relief . Préférez un logo plat .
Cliquez pour agrandir...
2. Vous n'avez pas d'icône
Pour ma part, j’ai pris un logo sur IconFinder , que j’ai converti en icône sur ConvertIco , et j’ai ajouté des marges au fichier original sur Paint .NET . J’suis quelqu'un de polyvalent, moi.
Figure 5 - Le logo que j'ai choisi pour mon lanceur
Après avoir choisi votre icône, il vous reste à créer un contrôle Image avec les propriétés HorizontalAlignment à Left , VerticalAlignment à Top , et de taille 40 pixels .
La propriété Source doit être le chemin vers le logo préalablement placé dans vos ressources, soit quelque chose comme /Graphical Launcher;component/Resources/logo.png .
Voici le code XAML :
Code (xml):
<Image x:Name ="IMG_LOGO" HorizontalAlignment ="Left" Height ="40" VerticalAlignment ="Top" Width ="40" Source ="/Graphical Launcher;component/Resources/logo_margin.png" Stretch ="Fill" />
Enfin, pour le titre, vous devrez importer la police Roboto Thin , Regular et Medium dans vos ressources, et créer une nouvelle étiquette avec les propriétés suivantes : Font Family à #Roboto Medium , Content à Lanceur Minecraft (ou ce que vous voulez, mais évitez le franglais du genre "Launcher by Albertodu84" ou la version du genre "Modpackcraft v02", qui ne font pas du tout professionnels ), HorizontalAlignment à Left , VerticalAlignment à Top , VerticalContentAlignment à Center , Height à 40 , TextHintingMode à Animated , FontSize à 18.5 , et MaxWidth à 800 .
Voici le code XAML :
Code (xml):
<Label x:Name ="LBL_NAME" FontFamily ="/Graphical Launcher;component/Resources/#Roboto Medium" Content ="Lanceur Minecraft" HorizontalAlignment ="Left" VerticalAlignment ="Top" VerticalContentAlignment ="Center" Height ="40" Foreground ="White" TextOptions.TextHintingMode ="Animated" FontSize ="18.667" Background ="{x:Null}" Margin ="40,0,0,0" MaxWidth ="800" />
Votre XAML devrait, pour le moment, ressembler à ça :
Code (xml):
<Window x:Name ="Lanceur" x:Class ="Graphical_Launcher.MainWindow"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local ="clr-namespace:Graphical_Launcher"
mc:Ignorable ="d"
Title ="Lanceur" Height ="600" Width ="1000" WindowStyle ="None" ResizeMode ="NoResize" >
<!-- Background -->
<Window.Background>
<ImageBrush ImageSource ="/Graphical Launcher;component/Resources/background.png" Stretch ="UniformToFill" />
</Window.Background>
<!-- Resources -->
<Window.Resources>
<!-- ControlBox Label -->
<Style x:Key ="ControlBoxLabel" TargetType ="Label" >
<Setter Property ="Background" Value ="Transparent" />
<Setter Property ="BorderBrush" Value ="Transparent" />
<Setter Property ="FontFamily" Value ="/Graphical Launcher;component/Resources/#Material Icons" />
<Setter Property ="HorizontalAlignment" Value ="Right" />
<Setter Property ="VerticalAlignment" Value ="Top" />
<Setter Property ="HorizontalContentAlignment" Value ="Center" />
<Setter Property ="VerticalContentAlignment" Value ="Center" />
<Setter Property ="Height" Value ="40" />
<Setter Property ="Width" Value ="40" />
<Setter Property ="TextOptions.TextHintingMode" Value ="Animated" />
<Setter Property ="FontSize" Value ="22.667" />
<Setter Property ="Foreground" Value ="#FFBDBDBD" />
<Setter Property ="Cursor" Value ="Hand" />
</Style>
</Window.Resources>
<!-- Content -->
<Grid>
<Rectangle x:Name ="ControlBox" Fill ="#99000000" Height ="40" Margin ="0" VerticalAlignment ="Top" />
<Label x:Name ="LBL_CLOSE" Style ="{StaticResource ControlBoxLabel}" Content ="" MouseLeftButtonUp ="LBL_CLOSE_MouseLeftButtonUp" />
<Label x:Name ="LBL_REDUCE" Style ="{StaticResource ControlBoxLabel}" Content ="" Margin ="0,0,40,0" MouseLeftButtonUp ="LBL_REDUCE_MouseLeftButtonUp" />
<Image x:Name ="IMG_LOGO" HorizontalAlignment ="Left" Height ="40" VerticalAlignment ="Top" Width ="40" Source ="/Graphical Launcher;component/Resources/logo_margin.png" Stretch ="Fill" />
<Label x:Name ="LBL_NAME" FontFamily ="/Graphical Launcher;component/Resources/#Roboto Medium" Content ="Lanceur Minecraft" HorizontalAlignment ="Left" VerticalAlignment ="Top" VerticalContentAlignment ="Center" Height ="40" Foreground ="White" TextOptions.TextHintingMode ="Animated" FontSize ="18.667" Background ="{x:Null}" Margin ="40,0,0,0" MaxWidth ="800" />
</Grid>
</Window>
3 . Les animations
Ceci étant fait, nous allons animer nos boutons de réduction et de fermeture , pour un meilleur rendu.
Cette partie devient relativement intéressante, puisque nous allons voir l'héritance des styles en WPF.
Je vous invite à éditer votre style ControlBoxLabel et d'y ajouter le code suivant :
Code (xml):
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value ="True" >
<!-- On MouseOver -->
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Background).(SolidColorBrush.Color)"
From ="#00000000" To ="#3F000000" Duration ="0:0:0.250" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<!-- On MouseLeave -->
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Background).(SolidColorBrush.Color)"
From ="#3F000000" To ="#00000000" Duration ="0:0:0.250" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
Ce code permet, au déclenchement de l'évènement IsMouseOver (ligne 2) de lancer une animation en fonction de la valeur de la propriété IsMouseOver (booléenne ), d'une durée de 250 millisecondes .
Quand vous passerez votre souris sur l'étiquette, l'animation (ColorAnimation ) à la ligne 8 (EnterAction ) se déclenchera, et fera passer l'opacité du fond de votre label à 25% , et l'inverse lorsque vous quitterez l'étiquette (ligne 15).
Vous pouvez lancer et voir le résultat.
Je vais aller plus loin en modifiant séparemment la couleur du texte des étiquettes ; soit en rouge pour la fermeture et en bleu pour la réduction.
Je vous invite à choisir les couleurs qui vous intéresse sur la page des couleurs Material de Google.
Pour moi ce sera le code 300 rouge (#e57373 ) pour la fermeture et le code 300 bleu (#4FC3F7 ) pour la réduction.
Une fois vos couleurs choisies, créez un nouvel évènement ControlBoxCloseLabel avec la propriété BasedOn à {StaticResource ControlBoxLabel} (principe d'héritance ) et avec deux animations jouant sur la propriété Label.Foreground qui ira vers votre couleur, et qui sera d'une durée de 500 millisecondes .
Voici le code XAML :
Code (xml):
<!-- Close button -->
<Style x:Key ="ControlBoxCloseLabel" TargetType ="Label" BasedOn ="{StaticResource ControlBoxLabel}" >
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value ="True" >
<!-- On MouseOver -->
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Foreground).(SolidColorBrush.Color)"
From ="#FFBDBDBD" To ="#ffe57373" Duration ="0:0:0.500" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<!-- On MouseLeave -->
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Foreground).(SolidColorBrush.Color)"
From ="#ffe57373" To ="#FFBDBDBD" Duration ="0:0:0.500" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
Vous pouvez maintenant faire pareil pour le bouton de réduction en changeant les couleurs et le nom.
En voici le code XAML :
Code (cpp):
< ! -- Close button -- >
< Style x: Key= "ControlBoxReduceLabel" TargetType= "Label" BasedOn= "{StaticResource ControlBoxLabel}" >
< Style.Triggers >
< Trigger Property= "IsMouseOver" Value= "True" >
< ! -- On MouseOver -- >
< Trigger.EnterActions >
< BeginStoryboard>
< Storyboard>
< ColorAnimation Storyboard.TargetProperty = "(Label.Foreground).(SolidColorBrush.Color)"
From= "#FFBDBDBD" To= "#ff4FC3F7" Duration= "0:0:0.500" / >
< / Storyboard>
< / BeginStoryboard>
< / Trigger.EnterActions >
< ! -- On MouseLeave -- >
< Trigger.ExitActions >
< BeginStoryboard>
< Storyboard>
< ColorAnimation Storyboard.TargetProperty = "(Label.Foreground).(SolidColorBrush.Color)"
From= "#ff4FC3F7" To= "#FFBDBDBD" Duration= "0:0:0.500" / >
< / Storyboard>
< / BeginStoryboard>
< / Trigger.ExitActions >
< / Trigger>
< / Style.Triggers >
< / Style>
Vous n'avez plus qu'à changer la propriété Style de vos étiquette en ControlBoxReduceLabel et ControlBoxCloseLabel , et tester !
Figure 6 - État actuel de mon lanceur
Pour résumer, voici le code complet.
Code (xml):
<Window x:Name ="Lanceur" x:Class ="Graphical_Launcher.MainWindow"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local ="clr-namespace:Graphical_Launcher"
mc:Ignorable ="d"
Title ="Lanceur" Height ="600" Width ="1000" WindowStyle ="None" ResizeMode ="NoResize" >
<!-- Background -->
<Window.Background>
<ImageBrush ImageSource ="/Graphical Launcher;component/Resources/background.png" Stretch ="UniformToFill" />
</Window.Background>
<!-- Resources -->
<Window.Resources>
<!-- ControlBox Label -->
<Style x:Key ="ControlBoxLabel" TargetType ="Label" >
<Setter Property ="Background" Value ="Transparent" />
<Setter Property ="BorderBrush" Value ="Transparent" />
<Setter Property ="FontFamily" Value ="/Graphical Launcher;component/Resources/#Material Icons" />
<Setter Property ="HorizontalAlignment" Value ="Right" />
<Setter Property ="VerticalAlignment" Value ="Top" />
<Setter Property ="HorizontalContentAlignment" Value ="Center" />
<Setter Property ="VerticalContentAlignment" Value ="Center" />
<Setter Property ="Height" Value ="40" />
<Setter Property ="Width" Value ="40" />
<Setter Property ="TextOptions.TextHintingMode" Value ="Animated" />
<Setter Property ="FontSize" Value ="22.667" />
<Setter Property ="Foreground" Value ="#FFBDBDBD" />
<Setter Property ="Cursor" Value ="Hand" />
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value ="True" >
<!-- On MouseOver -->
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Background).(SolidColorBrush.Color)"
From ="#00000000" To ="#3F000000" Duration ="0:0:0.250" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<!-- On MouseLeave -->
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Background).(SolidColorBrush.Color)"
From ="#3F000000" To ="#00000000" Duration ="0:0:0.250" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
<!-- Close button -->
<Style x:Key ="ControlBoxCloseLabel" TargetType ="Label" BasedOn ="{StaticResource ControlBoxLabel}" >
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value ="True" >
<!-- On MouseOver -->
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Foreground).(SolidColorBrush.Color)"
From ="#FFBDBDBD" To ="#ffe57373" Duration ="0:0:0.500" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<!-- On MouseLeave -->
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Foreground).(SolidColorBrush.Color)"
From ="#ffe57373" To ="#FFBDBDBD" Duration ="0:0:0.500" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
<!-- Close button -->
<Style x:Key ="ControlBoxReduceLabel" TargetType ="Label" BasedOn ="{StaticResource ControlBoxLabel}" >
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value ="True" >
<!-- On MouseOver -->
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Foreground).(SolidColorBrush.Color)"
From ="#FFBDBDBD" To ="#ff4FC3F7" Duration ="0:0:0.500" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<!-- On MouseLeave -->
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Foreground).(SolidColorBrush.Color)"
From ="#ff4FC3F7" To ="#FFBDBDBD" Duration ="0:0:0.500" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<!-- Content -->
<Grid>
<Border x:Name ="WindowBorders" BorderBrush ="#99000000" BorderThickness ="2" />
<!-- Control Box -->
<Rectangle x:Name ="ControlBox" Fill ="#99000000" Height ="38" Margin ="2,2,2,0" VerticalAlignment ="Top" />
<Label x:Name ="LBL_CLOSE" Style ="{StaticResource ControlBoxCloseLabel}" Content ="" />
<Label x:Name ="LBL_REDUCE" Style ="{StaticResource ControlBoxReduceLabel}" Content ="" Margin ="0,0,40,0" />
<Image x:Name ="IMG_LOGO" HorizontalAlignment ="Left" Height ="40" VerticalAlignment ="Top" Width ="40" Source ="/Graphical Launcher;component/Resources/logo_margin.png" Stretch ="Fill" />
<Label x:Name ="LBL_NAME" FontFamily ="/Graphical Launcher;component/Resources/#Roboto Medium" Content ="Lanceur Minecraft" HorizontalAlignment ="Left" VerticalAlignment ="Top" VerticalContentAlignment ="Center" Height ="40" Foreground ="White" TextOptions.TextHintingMode ="Animated" FontSize ="18.667" Background ="{x:Null}" Margin ="40,0,0,0" MaxWidth ="800" />
</Grid>
</Window>
III . Le code de fermeture et réduction
Nous en somme à la partie la plus simple, soit le code de fermeture et de réduction.
Commencez par mettre la propriété AllowTransparency de notre Window à True .
Ajoutez ensuite ce code dans vos resources :
Code (xml):
<!-- Window Close Fade -->
<Storyboard x:Key ="WindowClose" Completed ="closeStoryBoard_Completed" >
<DoubleAnimation Storyboard.TargetProperty ="Opacity" To ="0" From ="1" Duration ="0:0:0.250" Storyboard.TargetName ="Lanceur" />
</Storyboard>
En remplaçant bien entendu Lanceur par le nom de votre fenêtre. Vous pouvez également changer le temps.
Il permettra, lors de son appel, de faire fondre la fenêtre.
Ouvrez maintenant l'évènement MouseLeftButtonUp de votre LBL_CLOSE .
Figure 7 - Évènement MouseLeftButtonUp
L'éditeur de code s'affiche et le code XAML s'est modifié pour lier cette nouvelle méthode à l'évènement.
Écrivez simplement this.Close(); dans cette méthode.
Créez ensuite une variable globale privée et booléenne nommée closeStoryBoardCompleted .
Ouvrez l'évènement Closing de votre Window .
Insérez-y le code suivant :
Code (csharp):
if ( ! closeStoryBoardCompleted)
{
Storyboard WindowClose = this . FindResource ( "WindowClose" ) as Storyboard;
WindowClose. Begin ( ) ;
e. Cancel = true ;
}
Remplacez bien entendu WindowClose par le nom de votre Storyboard, et n'oubliez pas d'importer Windows.Media.Animation et ComponentModel .
Ce code permet de lancer l'animation en d'empêcher la fermeture (en attendant que l'animation se termine), si et seulement si la variable closeStoryBoardCompleted est à False .
Maintenant, vous pouvez ajouter la méthode appelée à la fin de l'animation, soit :
Code (csharp):
private void closeStoryBoard_Completed( object sender, EventArgs e)
{
closeStoryBoardCompleted = true ;
this . Close ( ) ;
}
Ici, rien de particulier à comprendre, si ce n'est qu'on passe la variable closeStoryBoardCompleted à True afin de ne pas gêner l'évènement de fermeture.
Vous pouvez essayer de cliquer sur le bouton de fermeture, et votre fenêtre se fermera en fondu !
Pour la réduction, c'est aussi simple que d'écrire this.WindowState = WindowState.Minimized; dans la méthode de l'évènement MouseLeftButtonUp du LBL_REDUCE .
Bien que ce soit possible, j'ai décidé de ne pas mettre d'animation à la réduction pour le moment.
Voici le code XAML complet :
Code (xml):
<Window x:Name ="Lanceur" x:Class ="Graphical_Launcher.MainWindow"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local ="clr-namespace:Graphical_Launcher"
mc:Ignorable ="d"
Title ="Lanceur" Height ="600" Width ="1000" WindowStyle ="None" ResizeMode ="NoResize" Closing ="Lanceur_Closing" AllowsTransparency ="True" >
<!-- Background -->
<Window.Background>
<ImageBrush ImageSource ="/Graphical Launcher;component/Resources/background.png" Stretch ="UniformToFill" />
</Window.Background>
<!-- Resources -->
<Window.Resources>
<!-- Window Close Fade -->
<Storyboard x:Key ="WindowClose" Completed ="closeStoryBoard_Completed" >
<DoubleAnimation Storyboard.TargetProperty ="Opacity" To ="0" Duration ="0:0:0.250" Storyboard.TargetName ="Lanceur" />
</Storyboard>
<!-- ControlBox Label -->
<Style x:Key ="ControlBoxLabel" TargetType ="Label" >
<Setter Property ="Background" Value ="Transparent" />
<Setter Property ="BorderBrush" Value ="Transparent" />
<Setter Property ="FontFamily" Value ="/Graphical Launcher;component/Resources/#Material Icons" />
<Setter Property ="HorizontalAlignment" Value ="Right" />
<Setter Property ="VerticalAlignment" Value ="Top" />
<Setter Property ="HorizontalContentAlignment" Value ="Center" />
<Setter Property ="VerticalContentAlignment" Value ="Center" />
<Setter Property ="Height" Value ="40" />
<Setter Property ="Width" Value ="40" />
<Setter Property ="TextOptions.TextHintingMode" Value ="Animated" />
<Setter Property ="FontSize" Value ="22.667" />
<Setter Property ="Foreground" Value ="#FFBDBDBD" />
<Setter Property ="Cursor" Value ="Hand" />
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value ="True" >
<!-- On MouseOver -->
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Background).(SolidColorBrush.Color)"
From ="#00000000" To ="#3F000000" Duration ="0:0:0.250" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<!-- On MouseLeave -->
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Background).(SolidColorBrush.Color)"
From ="#3F000000" To ="#00000000" Duration ="0:0:0.250" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
<!-- Close button -->
<Style x:Key ="ControlBoxCloseLabel" TargetType ="Label" BasedOn ="{StaticResource ControlBoxLabel}" >
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value ="True" >
<!-- On MouseOver -->
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Foreground).(SolidColorBrush.Color)"
From ="#FFBDBDBD" To ="#ffe57373" Duration ="0:0:0.500" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<!-- On MouseLeave -->
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Foreground).(SolidColorBrush.Color)"
From ="#ffe57373" To ="#FFBDBDBD" Duration ="0:0:0.500" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
<!-- Close button -->
<Style x:Key ="ControlBoxReduceLabel" TargetType ="Label" BasedOn ="{StaticResource ControlBoxLabel}" >
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value ="True" >
<!-- On MouseOver -->
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Foreground).(SolidColorBrush.Color)"
From ="#FFBDBDBD" To ="#ff4FC3F7" Duration ="0:0:0.500" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<!-- On MouseLeave -->
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty ="(Label.Foreground).(SolidColorBrush.Color)"
From ="#ff4FC3F7" To ="#FFBDBDBD" Duration ="0:0:0.500" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<!-- Content -->
<Grid>
<Border x:Name ="WindowBorders" BorderBrush ="#99000000" BorderThickness ="2" />
<!-- Control Box -->
<Rectangle x:Name ="ControlBox" Fill ="#99000000" Height ="38" Margin ="2,2,2,0" VerticalAlignment ="Top" />
<Label x:Name ="LBL_CLOSE" Style ="{StaticResource ControlBoxCloseLabel}" Content ="" MouseLeftButtonUp ="LBL_CLOSE_MouseLeftButtonUp" />
<Label x:Name ="LBL_REDUCE" Style ="{StaticResource ControlBoxReduceLabel}" Content ="" Margin ="0,0,40,0" MouseLeftButtonUp ="LBL_REDUCE_MouseLeftButtonUp" />
<Image x:Name ="IMG_LOGO" HorizontalAlignment ="Left" Height ="40" VerticalAlignment ="Top" Width ="40" Source ="/Graphical Launcher;component/Resources/logo_margin.png" Stretch ="Fill" />
<Label x:Name ="LBL_NAME" FontFamily ="/Graphical Launcher;component/Resources/#Roboto Medium" Content ="Lanceur Minecraft" HorizontalAlignment ="Left" VerticalAlignment ="Top" VerticalContentAlignment ="Center" Height ="40" Foreground ="White" TextOptions.TextHintingMode ="Animated" FontSize ="18.667" Background ="{x:Null}" Margin ="40,0,0,0" MaxWidth ="800" />
</Grid>
</Window>
Ainsi que le code-behind complet (il est très mal organisé, mais ce n'était pas le but de ce tutoriel) :
Code (csharp):
using System ;
using System.ComponentModel ;
using System.Windows ;
using System.Windows.Input ;
using System.Windows.Media.Animation ;
namespace Graphical_Launcher
{
/// <summary>
/// Logique d'interaction pour MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
// Variables
private bool closeStoryBoardCompleted = false ;
// Constructor
public MainWindow( )
{
InitializeComponent( ) ;
}
// Storyboard's end event
private void closeStoryBoard_Completed( object sender, EventArgs e)
{
closeStoryBoardCompleted = true ;
this . Close ( ) ;
}
// Form closing event
private void Lanceur_Closing( object sender, CancelEventArgs e)
{
if ( ! closeStoryBoardCompleted)
{
Storyboard WindowClose = this . FindResource ( "WindowClose" ) as Storyboard;
WindowClose. Begin ( ) ;
e. Cancel = true ;
}
}
// Button close event
private void LBL_CLOSE_MouseLeftButtonUp( object sender, MouseButtonEventArgs e)
{
this . Close ( ) ;
}
private void LBL_REDUCE_MouseLeftButtonUp( object sender, MouseButtonEventArgs e)
{
this . WindowState = WindowState. Minimized ;
}
}
}
Vous savez maintenant créer un design largement potable en WPF, et avez quelques conseils pour la création d'un design original.
Vous n'avez plus d'excuses, vous pouvez créer un joli lanceur ! :)
Si j'ai oublié quelque chose, ou que vous avez besoin de détails, n'hésitez pas à commenter.