【问题标题】:WPF TriState Image ButtonWPF 三态图像按钮
【发布时间】:2011-01-30 07:41:47
【问题描述】:

有没有人有任何关于创建三态图像按钮的建议?

我有以下内容,但我真正想做的是拥有一个具有多个 ImageSource 属性的控件,例如 <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>

【问题讨论】:

    标签: wpf image button


    【解决方案1】:

    我自己也遇到过同样的问题。我在这里创建了一个开源项目http://imagebuttonwpf.codeplex.com,您可以在其中获取最新版本的图像按钮。 我不喜欢提供的“接受”解决方案有几个原因(尽管它是一个更轻量级的解决方案并且有其自身的优势)

    Blockquote 这个 StackOverflow 问题的公认答案显示了一种简单的方法:WPF - How to create image button with template

    主要是我认为覆盖您想要更改图像的每个按钮的控件模板是不正确的,因此我创建了一个名为 ImageButton 的自定义控件。它从按钮扩展以具有它的任何功能(尽管它可以很容易地从内容控件扩展),但还包含一个可以在不重写整个控件模板的情况下设置样式的图像。 我不喜欢每次都为我的按钮重写整个控件模板的另一个原因是我的基本按钮样式包含多个边框和动画效果,用于鼠标悬停、按下等。每次重写这些显然有其自身的冗余问题。 反正这里是 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
    

    接下来我们需要为我们的按钮提供一个默认控件模板,我从这个按钮中取出了我的大部分边框等,一个条形图,这样您就可以看到它在我们所有的样式中都被继承了

    <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>
    

    那么我们当然需要新图片按钮的默认样式

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

    当然,使用这种方法的好处是我创建了一个基于父样式的样式,它使用 Setter 来更改依赖属性(而不是需要覆盖控件模板 - 目标)

    <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>
    

    最后这意味着可以通过几种不同的方式声明按钮,或者在 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"/>
    

    或者使用样式

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

    希望对你有帮助

    【讨论】:

    • 您可以在 codeproject.net 上为此写一篇文章,使用这样的解决方案 :) 还有一件事,您可以添加 ImageButton 控件的示例使用代码吗?我们会更容易快速应用您的解决方案。
    • 如果您从那里下载版本,我已将其创建为 codeplex imagebuttonwpf.codeplex.com 上的项目,它已在项目中进行了所有设置。
    【解决方案2】:

    这个 StackOverflow 问题的公认答案显示了一种简单的方法: WPF - How to create image button with template

    您在 IsEnabled 和 IsPressed 属性上创建属性触发器,并根据需要显示或隐藏图像。

    正如 Avanka 在他的回答中指出的那样,您需要创建依赖属性来设置图像的路径。

    【讨论】:

    • 该问题没有公认的答案。投票最高的答案也不能真正回答问题;它不是一个非常可重用的控件,因为该样式有 3 个硬编码的图像路径。
    • 如果您需要能够更改样式或模板中的某些内容,例如按钮文本或图像路径,您可以使用附加属性,如下所示:stackoverflow.com/a/650620/724944
    【解决方案3】:

    理想情况下,您必须创建一个继承自 Button 的自定义控件。添加三个依赖属性,并为新控件创建默认样式。

    您可以检查 ImageButton 库中的 ImageButton 类 - 它完全符合您的要求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-28
      相关资源
      最近更新 更多