2009-06-04 17 views
2

Sur le blog Nerd Plus Art aujourd'hui, il y avait un article sur la création de ressources WPF pour les flèches, que l'auteur utilise fréquemment. J'ai un projet de côté qui a des boutons Précédent et Suivant, donc j'ai pensé que les flèches Gauche et Droite fonctionneraient très bien sur ces boutons.Créer un WPF ValueConverter pour un pinceau

J'ai ajouté les LeftArrow et RightArrow Géométries aux ressources de mon application, puis les a utilisées comme contenu des boutons:

<Application x:Class="Notes.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    StartupUri="Views/MainWindow.xaml"> 
    <Application.Resources> 
     <Geometry x:Key="RightArrow">M0,0 L1,0.5 0,1Z</Geometry> 
     <Geometry x:Key="LeftArrow">M0,0.5 L1,1 1,0Z</Geometry> 
    </Application.Resources> 
</Application> 

<Button x:Name="BackButton" 
    Padding="5,5,5,5" 
    Command="{x:Static n:Commands.GoBackCommand}"> 
    <Path Data="{StaticResource LeftArrow}" Width="10" Height="8" 
     Stretch="Fill" Fill="Black"/> 
    </Button> 
<Button x:Name="ForwardButton" 
    Padding="5,5,5,5" 
    Command="{x:Static n:Commands.GoForwardCommand}"> 
    <Path Data="{StaticResource RightArrow}" Width="10" Height="8" 
     Stretch="Fill" Fill="Red" /> 
</Button> 

Cela a fonctionné, sauf que les flèches ont été tirées en noir, que le bouton a été activé ou non. Donc, j'ai créé un ValueConverter pour passer d'un bool à un Brush:

class EnabledColorConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, 
     CultureInfo culture) 
    { 
     bool b = (bool)value; 
     return b ? Brushes.Black : Brushes.Gray; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, 
     CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

(je me rends compte que je devrais probablement utiliser des couleurs du système au lieu du disque codé en noir et gris, mais je voulais juste obtenir ce travail, d'abord .)

I modifié la Fill propriété du Path utiliser mon convertisseur (que j'ai créé au sein de la ressources de l'application):

<Path Data="{StaticResource LeftArrow}" Width="10" Height="8" 
    Stretch="Fill" 
    Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=IsEnabled, Converter={StaticResource EnabledColorConverter}}"/> 

Malheureusement, cela ne w ork, et je ne sais pas pourquoi. Quand je l'exécute, la flèche n'est pas dessinée du tout. J'ai vérifié la fenêtre de sortie dans Visual Studio, et aucune erreur de liaison n'a été affichée. J'ai également vérifié que le bool est la bonne valeur dans le convertisseur, selon si le bouton devrait être activé ou non.

Si je change le Path retour à un TextBlock (et lier sa propriété Foreground de la même manière que Path.Fill), le texte est toujours dessiné en noir.

Est-ce que je fais quelque chose de mal? Pourquoi le Brush retourné par mon convertisseur n'est-il pas utilisé pour afficher le Path dans le bouton?

+0

Je ne sais pas pourquoi votre code ne fonctionne pas, mais j'aurais utilisé des déclencheurs de style pour cela ... – Will

Répondre

2

Pourquoi pas qu'affecter le remplissage de votre chemin au premier plan du bouton?

<Button x:Name="BackButton" 
    Padding="5,5,5,5" 
    Command="{x:Static n:Commands.GoBackCommand}"> 
    <Path Data="{StaticResource LeftArrow}" Width="10" Height="8" 
     Stretch="Fill" Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=Foreground"/> 
    </Button> 
+0

Ce serait une approche beaucoup plus directe, et cela fonctionne. Merci pour l'aide. :) – Andy

0

Votre code fonctionne essentiellement. Je pense que votre ressource statique peut être erronée car vous ne spécifiez pas d'où provient le convertisseur.

Vous avez probablement

<Window.Resources> 
    <conv:EnabledColorConverter x:Key="brushConv" /> 
</Window.Resources> 

puis spécifiez votre fixation comme:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=IsEnabled, Converter={StaticResource brushConv}} 
+0

J'ai le convertisseur défini dans Application.Resources - Je ne l'ai pas inclus dans le code ci-dessus. Désolé pour la confusion. – Andy

2

Pour ce type de mises à jour d'état de l'interface utilisateur, essayez plutôt d'utiliser des déclencheurs; cela vous évitera d'écrire un convertisseur de valeur, et il est beaucoup plus court d'écrire.

Essayez ceci:

<Application x:Class="Notes.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    StartupUri="Views/MainWindow.xaml"> 
    <Application.Resources> 
     <Geometry x:Key="RightArrow">M0,0 L1,0.5 0,1Z</Geometry> 
     <Geometry x:Key="LeftArrow">M0,0.5 L1,1 1,0Z</Geometry> 

     <!-- Base Arrow Style, with a trigger to toggle it Gray when its parent button is disabled --> 
     <Style x:Key="ArrowStyle" TargetType="Path"> 
      <Setter Property="Width" Value="10"/> 
      <Setter Property="Height" Value="8"/> 
      <Setter Property="Stretch" Value="Fill"/> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=IsEnabled}" Value="False"> 
        <Setter Property="Fill" Value="Gray"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 

     <!-- Left Arrow Style, with the Left Arrow fill and data --> 
     <Style x:Key="LeftArrowStyle" BasedOn="{StaticResource ArrowStyle}" TargetType="Path"> 
      <Setter Property="Fill" Value="Black"/> 
      <Setter Property="Data" Value="{StaticResource LeftArrow}"/> 
     </Style> 

     <!-- Right Arrow Style, with the Right Arrow fill and data --> 
     <Style x:Key="RightArrowStyle" BasedOn="{StaticResource ArrowStyle}" TargetType="Path"> 
      <Setter Property="Fill" Value="Red"/> 
      <Setter Property="Data" Value="{StaticResource RightArrow}"/> 
     </Style> 
    </Application.Resources> 

    <Button x:Name="BackButton" Padding="5,5,5,5" IsEnabled="False"> 
     <Path Style="{StaticResource LeftArrowStyle}"/> 
    </Button> 
    <Button x:Name="ForwardButton" Padding="5,5,5,5"> 
     <Path Style="{StaticResource RightArrowStyle}"/> 
    </Button> 
</Application> 

Ensuite, vous définissez votre défaut remplir LeftArrowStyle et RightArrowStyle, pour les flèches gauche et droite, respectivement. Si vous le définissez sur le chemin lui-même, cette valeur aurait la priorité et remplacerait tout ce qu'un style ou son déclencheur pourrait faire. Le style de base, ArrowStyle, contient un DataTrigger lié au bouton parent - il se déclenche chaque fois que IsEnabled est faux, et modifie le Fill du chemin en Gray.

+0

Je pense que je vais aller avec l'approche de ppx de liaison au premier plan du bouton semble directement comme une meilleure approche. Encore, merci pour la réponse très informative. :) – Andy