2010-03-22 6 views
3

Est-ce que quelqu'un a des pointeurs pour créer un bouton d'image à trois états?Bouton WPF TriState Image

Je donne les résultats suivants, mais ce que je veux vraiment faire est d'avoir un contrôle avec plusieurs propriétés de ImageSource comme <Controls.TristateButton Image="" HoverImage="" PressedImage="" />

<Style TargetType="{x:Type Button}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type Button}"> 
       <StackPanel Orientation="Horizontal" > 
        <Image Name="PART_Image" Source="path to normal image" /> 
       </StackPanel> 
       <ControlTemplate.Triggers> 
        <Trigger Property="IsMouseOver" Value="True"> 
         <Setter Property="Source" Value="path to mouse over image" TargetName="PART_Image"/> 
        </Trigger> 
        <Trigger Property="IsPressed" Value="True"> 
         <Setter Property="Source" Value="path to pressed image" TargetName="PART_Image"/> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Répondre

3

La réponse acceptée à cette question StackOverflow montre un moyen facile de le faire: WPF - How to create image button with template

Vous créez la propriété se déclenche sur les propriétés IsEnabled et IsPressed et afficher ou masquer les images au besoin. Comme Avanka l'a noté dans sa réponse, vous devrez créer des propriétés de dépendance pour définir les chemins d'accès aux images.

+1

Il n'y a pas de réponse acceptée à cette question. De plus, la réponse la mieux votée ne répond pas vraiment à la question; ce n'est pas un contrôle très réutilisable puisque le style a 3 chemins d'image codés en dur. –

+0

Si vous devez pouvoir modifier quelque chose dans le style ou le modèle, par exemple le texte du bouton ou le chemin de l'image, vous pouvez utiliser les propriétés attachées comme ceci: http://stackoverflow.com/a/650620/724944 – surfen

3

, vous avez idéalement pour créer un contrôle personnalisé, hérité de Button. Ajoutez trois propriétés de dépendance et créez un style par défaut pour le nouveau contrôle.

Vous pouvez vérifier la classe ImageButton de la bibliothèque FluidKit - elle fait exactement ce que vous voulez.

18

J'ai moi-même rencontré le même problème. J'ai créé un projet open source ici http://imagebuttonwpf.codeplex.com où vous pouvez obtenir la dernière version du bouton Image. Je n'aime pas la solution « acceptée » prévue pour plusieurs raisons (bien qu'il soit une solution plus légère et a ses propres avantages)

Blockquote La réponse acceptée à cette question StackOverflow montre un moyen facile de le faire: WPF - How to create image button with template

Principalement, je ne pense pas que son correct pour remplacer le modèle de contrôle pour chaque bouton que vous souhaitez modifier l'image pour donc j'ai créé un contrôle personnalisé appelé ImageButton. Il s'étend à partir du bouton afin d'avoir une quelconque fonctionnalité (bien qu'il puisse être capable de s'étendre aussi facilement depuis le contrôle de contenu) mais contient également une image qui peut être stylée sans réécrire le modèle de contrôle entier. Une autre raison pour laquelle je n'aime pas réécrire chaque fois le modèle de contrôle pour mon bouton est que mon style de bouton de base contient plusieurs bordures et effets d'animation pour la souris, est pressé, etc .. Réécrire chaque fois a évidemment ses propres problèmes de redondance. Quoi qu'il en soit ici est la classe ImageButton

public class ImageButton : Button 
{ 
static ImageButton() { 
    DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton))); 
} 

#region Dependency Properties 

public double ImageSize 
{ 
    get { return (double)GetValue(ImageSizeProperty); } 
    set { SetValue(ImageSizeProperty, value); } 
} 

public static readonly DependencyProperty ImageSizeProperty = 
    DependencyProperty.Register("ImageSize", typeof(double), typeof(ImageButton), 
    new FrameworkPropertyMetadata(30.0, FrameworkPropertyMetadataOptions.AffectsRender, ImageSourceChanged)); 

public string NormalImage 
{ 
    get { return (string)GetValue(NormalImageProperty); } 
    set { SetValue(NormalImageProperty, value); } 
} 

public static readonly DependencyProperty NormalImageProperty = 
    DependencyProperty.Register("NormalImage", typeof(string), typeof(ImageButton), 
    new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender,ImageSourceChanged)); 

public string HoverImage 
{ 
    get { return (string)GetValue(HoverImageProperty); } 
    set { SetValue(HoverImageProperty, value); } 
} 

public static readonly DependencyProperty HoverImageProperty = 
    DependencyProperty.Register("HoverImage", typeof(string), typeof(ImageButton), 
    new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender, ImageSourceChanged)); 

public string PressedImage 
{ 
    get { return (string)GetValue(PressedImageProperty); } 
    set { SetValue(PressedImageProperty, value); } 
} 

public static readonly DependencyProperty PressedImageProperty = 
    DependencyProperty.Register("PressedImage", typeof(string), typeof(ImageButton), 
    new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender, ImageSourceChanged)); 

public string DisabledImage 
{ 
    get { return (string)GetValue(DisabledImageProperty); } 
    set { SetValue(DisabledImageProperty, value); } 
} 

public static readonly DependencyProperty DisabledImageProperty = 
    DependencyProperty.Register("DisabledImage", typeof(string), typeof(ImageButton), 
    new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender, ImageSourceChanged)); 

private static void ImageSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
{ 
    Application.GetResourceStream(new Uri("pack://application:,,," + (string) e.NewValue)); 
} 

#endregion 

Ensuite, nous avons besoin de fournir un modèle de contrôle par défaut pour notre bouton ive pris la plupart de mes frontières, etc de celui-ci, sauf un, vous pouvez donc voir qu'il est hérité tout au long tous nos styles

<ControlTemplate x:Key="ImageButtonTemplate" TargetType="{x:Type Controls:ImageButton}"> 
<Grid x:Name="Grid"> 
    <Border x:Name="Background" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3" /> 
    <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"> 
    <Image x:Name="ButtonImage" Source="{Binding NormalImage, RelativeSource={RelativeSource TemplatedParent}}" 
      Height="{Binding ImageSize, RelativeSource={RelativeSource TemplatedParent}}" 
      Width="{Binding ImageSize, RelativeSource={RelativeSource TemplatedParent}}"/> 
    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True" /> 
    </StackPanel>  
</Grid> 
<ControlTemplate.Triggers> 
    <Trigger Property="IsMouseOver" Value="true"> 
    <Setter TargetName="ButtonImage" Property="Source" Value="{Binding HoverImage, RelativeSource={RelativeSource TemplatedParent}}" /> 
    </Trigger> 
    <Trigger Property="IsPressed" Value="true"> 
    <Setter TargetName="ButtonImage" Property="Source" Value="{Binding PressedImage, RelativeSource={RelativeSource TemplatedParent}}" /> 
    </Trigger> 
    <Trigger Property="IsEnabled" Value="false"> 
    <Setter TargetName="ButtonImage" Property="Source" Value="{Binding DisabledImage, RelativeSource={RelativeSource TemplatedParent}}" /> 
    </Trigger> 
</ControlTemplate.Triggers> 

alors bien sûr nous avons besoin d'un style par défaut pour notre nouveau bouton d'image

<Style TargetType="{x:Type Controls:ImageButton}" BasedOn="{x:Null}"> 
<Setter Property="Template" Value="{StaticResource ImageButtonTemplate}" /> 
</Style> 

Et bien sûr, les avantages de l'utilisation de cette méthode i ont créé un style basé sur le style de parent qui utilise un Setter pour modifier les propriétés de dépendance (au lieu de nécessaire pour remplacer le modèle de contrôle - l'objectif)

<Style x:Key="TestImageButton" TargetType="{x:Type Controls:ImageButton}" BasedOn="{StaticResource {x:Type Controls:ImageButton}}"> 
<Setter Property="NormalImage" Value="/ImageButton;component/Resources/clear.png"/> 
<Setter Property="HoverImage" Value="/ImageButton;component/Resources/clear_green.png" /> 
<Setter Property="PressedImage" Value="/ImageButton;component/Resources/clear_darkgreen.png" /> 
<Setter Property="DisabledImage" Value="/ImageButton;component/Resources/clear_grey.png" /> 
</Style> 

et enfin, cela signifie que l'on peut déclarer le bouton dans quelques différentes manières, soit déclarer le chemin de l'image dans le XAML

<Controls:ImageButton 
    Content="Test Button 1" 
    NormalImage="/ImageButton;component/Resources/edit.png" 
    HoverImage="/ImageButton;component/Resources/edit_black.png" 
    PressedImage="/ImageButton;component/Resources/edit_darkgrey.png" 
    DisabledImage="/ImageButton;component/Resources/edit_grey.png"/> 

Ou bien utiliser le style

<Controls:ImageButton 
    Content="Test Button 2" 
    Style="{DynamicResource TestImageButton}"/> 

Espérons que cela aide

+0

Vous pouvez écrire un article pour cela sur codeproject.net avec une telle solution :) Encore une chose, pouvez-vous ajouter un exemple de codes d'utilisation de votre contrôle ImageButton? Il nous serait beaucoup plus facile d'appliquer votre solution rapidement. –

+0

J'ai créé ceci comme un projet sur http://codebuttonwpf.codeplex.com/ codeplex si vous téléchargez la version à partir de laquelle il a tout configuré dans un projet. – PJUK