VisualStateManager — montrant le passage de la souris de l'état lorsque le contrôle est axé
Je suis entrain de créer un WPF bouton à l'aide de Windows 8 style (anciennement metro).
Je voudrais l'état condensé de la touche pour afficher avec un arrière-plan solide. Lorsque la souris est sur le contrôle, je voudrais th fond pour assombrir légèrement pour créer le repère visuel que le bouton peut être cliqué.
Malheureusement, le code XAML j'ai écrit ci-dessous ne fonctionne pas. Le concentré d'état affiche correctement, mais lorsque la souris est sur le contrôle, le fond ne fonce pas comme je le voudrais.
<Color x:Key="DoxCycleGreen">
#FF8DC63F
</Color>
<!-- Soft Interface : DoxCycle Green -->
<Color x:Key="DoxCycleGreenSoft">
#FFC0DC8F
</Color>
<Style x:Key="MetroButton" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="RootElement">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal" />
<VisualState Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor" Storyboard.TargetProperty="Color" To="{StaticResource DoxCycleGreen}" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor" Storyboard.TargetProperty="Color" To="White" Duration="0:0:0.150" />
</Storyboard>
</VisualState>
<VisualState Name="Focused">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor" Storyboard.TargetProperty="Color" To="{StaticResource DoxCycleGreenSoft}" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor" Storyboard.TargetProperty="Color" To="White" Duration="0:0:0.150" />
</Storyboard>
</VisualState>
<VisualState Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor" Storyboard.TargetProperty="Color" To="Transparent" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor" Storyboard.TargetProperty="Color" To="{StaticResource DoxCycleGreen}" Duration="0:0:0.150" />
</Storyboard>
</VisualState>
<VisualState Name="Disabled">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BorderColor" Storyboard.TargetProperty="Color" To="DarkGray" Duration="0:0:0.1" />
<ColorAnimation Storyboard.TargetName="FontColor" Storyboard.TargetProperty="Color" To="DarkGray" Duration="0:0:0.1" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Background="Transparent" >
<Border BorderThickness="1,1,1,1" Padding="2">
<Border.BorderBrush>
<SolidColorBrush x:Name="BorderColor" Color="{StaticResource DoxCycleGreen}"/>
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush x:Name="BackgroundColor" Color="White"/>
</Border.Background>
<ContentPresenter
x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Content">
<TextBlock.Foreground>
<SolidColorBrush x:Name="FontColor" Color="{StaticResource DoxCycleGreen}"/>
</TextBlock.Foreground>
</ContentPresenter>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Pouvez-vous ajouter quelques précisions? Vous voulez dire que le passage de la Souris de l'état jamais est appliqué, ou qu'elle n'est pas appliquée lorsque le bouton est également porté?
OriginalL'auteur Cameron Peters | 2013-01-31
Vous devez vous connecter pour publier un commentaire.
Maintenant, j'ai testé votre code. Vous avez un couple de questions en jeu ici. Mais le principal problème est que d'un contrôle WPF ne peut être que dans un État Visuel d'un État particulier du Groupe à la fois. Et dans le cas que vous avez ici, où le contrôle peut être les deux concentré et on passe la souris dessus, WPF a à faire des choix de l'État à appliquer (il ne peut pas appliquer les deux États, car ils sont dans le même État de Groupe). Donc dans ce cas c'est juste le garder en l'état Concentré et de ne pas l'envoyer à l'effet de Survol de l'état.
Un contrôle peut être dans plusieurs états à chacun de ces états sont dans différents groupes d'état. De cette documentation:
Notre première étape de la correction de ce code est de comprendre l'état des groupes qui permettra le bouton pour être en mesure de démontrer ses Concentré de l'état et de montrer ensuite son Survol de l'état (d'autres possibilités peuvent être corrigées par ce changement, mais c'est celui que vous avez remarqué en particulier que vous n'avez pas obtenir avec votre approche précédente).
Pour ce faire, nous devons être prudents pour le nom de notre état des groupes et (surtout) de notre état noms correctement. C'est parce que le code interne à la classe Button rend probable un appel comme
VisualStateManager.GoToState(this, "VerySpecificStateName", true);
(je n'ai pas inspecter le code source de la classe de Bouton pour vérifier cela, mais après avoir écrit des contrôles personnalisés où j'en ai eu besoin pour initier les changements d'état, je sais que cela doit être quelque chose comme ça). Afin d'obtenir une liste de l'état du groupe et de l'état noms que nous aurons besoin, on peut soit utiliser Expression Blend à "modifier une copie" du modèle de contrôle (qui remplit le besoin des états pour nous), ou de les trouver ici. Que la documentation nous indique que nous avons besoin d'un groupe d'état appelé "FocusStates" et de deux membres de ce groupe appelé "Focus" et "Floue" (avec d'autres groupes d'état et des états). En aparté, pour illustrer la façon dont le Bouton de classe est en train d'initier ses changements d'état par ces nommée unis, si vous modifiez votre code d'origine en remplaçant le "Focus" de l'état avec le nom "MisspelledFocus", vous verrez que votre bouton ne pénètre jamais dans cet état.La mise en œuvre de ce premier changement, nous pourrions nous retrouver avec quelque chose comme:
Un peu cela résout le problème. Toutefois, si vous êtes à la recherche à de cette dans Expression Blend, vous verrez un message d'avertissement dans l'état têtes de groupe:
Nous obtenons cet avertissement, car nous sommes à la modification de la valeur d'un bien identique/paire d'objets dans plus d'un groupe d'état - dans ce cas, la "Couleur" de la propriété de l'objet nommé "BackgroundColor". Pourquoi cela pourrait-il être un problème? Parce que de ce que j'ai dit plus tôt - le fait qu'un contrôle peut être dans plusieurs états à la fois si ces états sont dans les différents groupes d'état. Donc, si l'utilisateur a donné le bouton focus et que l'utilisateur a aussi les on passe la souris sur le bouton, il pourrait être ambigu de WPF qui d'animation à appliquer, puisque les deux états-dire pour animer la même propriété exacte, mais de manières différentes.
Aussi, cette première modification n'est pas entièrement de nous obtenir ce que nous voulons. Si vous essayez de donner le focus à un bouton, puis passez la souris dessus, cela correctement va de "Normal","", "Survol". Mais si vous interrompre en vol stationnaire, vous verrez que le bouton ne revient pas à sa le "focus" de l'état.
Il existe plusieurs approches que vous pouvez utiliser pour remédier à ce problème et de réaliser quelque chose de semblable à ce que tu voulais, mais juste comme exemple, nous pourrions faire quelque chose comme cela. (Cela peut ne pas être le plus propre de la mise en œuvre de cette, mais il fixe les communes de l'objet/propriété problème.):
Maintenant, vous allez voir que nous avons supprimé l'ambiguïté pour WPF. Et nous voyons qu'il gère désormais le cas de modifications de l'état de "Normal" à "Focus" pour "Survol" et de "Focus" correctement.
C'est parfait... un seul changement nécessaire. Chaque contenu présentateurs doit avoir la propriété RecognizesAccessKey="True" de sorte qu'il fonctionne comme un bouton microsoft... c'était un bug dans mon code source original, mais que j'ai maintenant corrigé.
Bon à savoir sur la RecognizesAccessKey. C'est une nouvelle pour moi aussi. Merci!
J'en ai trouvé une autre bizarrerie. La coupe courte boutons ne se déclenche plus d'appuyer sur un bouton quand il y a deux présentateurs. J'ai ajouté une autre réponse qui utilise uniquement un contenu unique presenter, mais je ne pense pas que l'animation de transition est aussi beau que le vôtre...
Ah, bonne prise!
OriginalL'auteur Jason Frank
C'est une petite modification de Jason réponse. Il s'avère que son approche qui utilise deux ContentPresenters sauts de l'opération de court touches de raccourci. J'ai fait un petit réglage... le raccourci touches de travail, mais l'animation de transition n'est pas aussi belle...
OriginalL'auteur Cameron Peters