如何使用自定义启用/禁用图像创建一个简单的 WPF UserControl 按钮?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4984917/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:34:39  来源:igfitidea点击:

How to create a simple WPF UserControl button with custom enabled/disabled images?

wpfimageuser-controlsbutton

提问by JustAMartin

I am a bit new to WPF and XAML, just learning now.

我对 WPF 和 XAML 有点陌生,现在才开始学习。

I found a quick-n-dirty code by some previous developer:

我发现了一些以前的开发人员的快速-n-dirty 代码:

<ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type Button}">
        <Border Name="buttonBorder" Background="{TemplateBinding Background}">
            <Border.Effect>
                <DropShadowEffect Opacity="0.0" />
            </Border.Effect>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="true">
                <Setter TargetName="buttonBorder" Property="Effect">
                    <Setter.Value>
                        <DropShadowEffect Opacity="0.8" />
                    </Setter.Value>
                </Setter>
            </Trigger>
            <Trigger Property="IsMouseCaptured" Value="true">
                    <Setter TargetName="buttonBorder" Property="Effect">                   
                         <Setter.Value>
                        <DropShadowEffect Opacity="0.8" Direction="135"  
                             ShadowDepth="3" BlurRadius="1" />
                        </Setter.Value>
                    </Setter>
                </Trigger>
            <Trigger Property="IsEnabled" Value="false">
                   <Setter TargetName="buttonBorder" Property="Background">
                        <Setter.Value>
                        <ImageBrush ImageSource="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}"  />
                        </Setter.Value>
                    </Setter>            
                   <Setter TargetName="buttonBorder" Property="Effect">
                    <Setter.Value>
                        <DropShadowEffect Opacity="0.0"/>
                    </Setter.Value>
                </Setter>     

            </Trigger>
        </ControlTemplate.Triggers>
        </ControlTemplate>

Basically it is just a template for a button with a basic mouseover effect and the image for disabled state bound to Tag (seems an ugly solution).

基本上它只是一个具有基本鼠标悬停效果的按钮模板和绑定到标签的禁用状态图像(似乎是一个丑陋的解决方案)。

I want to create a custom button which works pretty the same, but I want to expose two custom properties: NormalImage and DisabledImage. Those properties should be of type string not Uri. I want to use the path to image just "apply.png" and not "pack://application:,,,/Resources/Apply.png". I guess, to have such custom properties I need a UserControl with dependency properties?

我想创建一个工作原理完全相同的自定义按钮,但我想公开两个自定义属性:NormalImage 和 DisabledImage。这些属性应该是字符串类型而不是 Uri。我想使用图像路径只是“apply.png”而不是“pack://application:,,,/Resources/Apply.png”。我想,要拥有这样的自定义属性,我需要一个具有依赖属性的 UserControl 吗?

Basically, I want to use the button as follows:

基本上,我想按如下方式使用按钮:

<MyImageButton NormalImage="apply.png" DisabledImage="apply_disabled.png"/>

Maybe NormalImage/DisabledImage will be bound to something later but that's unlikely.

也许 NormalImage/DisabledImage 稍后会绑定到某些东西,但这不太可能。

I could not find any example which implements such a basic button with custom properties, there are only some fancy buttons and controls online. Maybe I am just using incorrect keywords...

我找不到任何实现具有自定义属性的基本按钮的示例,网上只有一些花哨的按钮和控件。也许我只是使用了不正确的关键字...

Could anyone point me to the right article or throw some simple piece of code to play with?

谁能指出我正确的文章或抛出一些简单的代码来玩?

WPF is so complicated for beginners, sometimes it just does not work as expected, for example I still do not understand why I can add Trigger tag to ControlTemplate, but I cannot add Trigger tag straight to UserControl...

WPF对于初学者来说太复杂了,有时它只是不能按预期工作,例如我仍然不明白为什么我可以将Trigger标签添加到ControlTemplate,但我不能直接将Trigger标签添加到UserControl...

回答by H.B.

You could also use a UserControlwhich is a bit messy since your button will be encapsulated, would look something like this:

您也可以使用UserControl有点乱的a ,因为您的按钮将被封装,看起来像这样:

Xaml:

Xml:

<UserControl x:Class="Test.ImageButton"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Button Name="button" Click="button_Click" Width="50" Height="50">
        <Button.Template>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Name="buttonBorder">
                    <Border.Effect>
                        <DropShadowEffect Opacity="0.0" />
                    </Border.Effect>
                    <Border.Child>
                        <Image Name="img" Source="{Binding NormalImage}"/>
                    </Border.Child>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter TargetName="buttonBorder" Property="Effect">
                            <Setter.Value>
                                <DropShadowEffect Opacity="0.8" />
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                    <Trigger Property="IsMouseCaptured" Value="true">
                        <Setter TargetName="buttonBorder" Property="Effect">
                            <Setter.Value>
                                <DropShadowEffect Opacity="0.8" Direction="135"  
                             ShadowDepth="3" BlurRadius="1" />
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter TargetName="img" Property="Source" Value="{Binding DisabledImage}"/>
                        <Setter TargetName="buttonBorder" Property="Effect">
                            <Setter.Value>
                                <DropShadowEffect Opacity="0.0"/>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Button.Template>
    </Button>
</UserControl>

Code behind:

后面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Test
{
    /// <summary>
    /// Interaction logic for ImageButton.xaml
    /// </summary>
    public partial class ImageButton : UserControl
    {
        public ImageSource DisabledImage
        {
            get { return (ImageSource)GetValue(DisabledImageProperty); }
            set { SetValue(DisabledImageProperty, value); }
        }
        public static readonly DependencyProperty DisabledImageProperty =
            DependencyProperty.Register("DisabledImage", typeof(ImageSource), typeof(ImageButton), new UIPropertyMetadata(null));


        public ImageSource NormalImage
        {
            get { return (ImageSource)GetValue(NormalImageProperty); }
            set { SetValue(NormalImageProperty, value); }
        }
        public static readonly DependencyProperty NormalImageProperty =
            DependencyProperty.Register("NormalImage", typeof(ImageSource), typeof(ImageButton), new UIPropertyMetadata(null));

        public event RoutedEventHandler Click;

        public ImageButton()
        {
            InitializeComponent();
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            if (Click != null)
            {
                Click(this, e);
            }
        }
    }
}

Example usage:

用法示例:

        <local:ImageButton x:Name="imgbutton"
                           NormalImage="C:/1.png"
                           DisabledImage="C:/2.png"
                           Click="ImgButton_Click"/>

(Note that the current namespace is Test, you might want to change that; Also i set a fixed size on the internal button, which you might want to remove, just make sure to set the size somewhere since i think it will not use any space at all if you don't.)

(请注意,当前的命名空间是Test,您可能想要更改它;此外,我在内部按钮上设置了一个固定大小,您可能想要删除它,只需确保在某处设置大小,因为我认为它不会使用任何空间如果你不这样做。)

回答by Snowbear

This is how I see it:

这是我的看法:

1) Create your MyImageButtonclass which should inherit regular Buttonand include two dependency properties - NormalImageand DisabledImage. These properties should be of ImageSourcetype. See here how to define dependency properties: http://msdn.microsoft.com/en-us/library/ms752914.aspx#back_dependency_properties

1)创建您的MyImageButton类,该类应该继承常规Button并包含两个依赖项属性 -NormalImageDisabledImage. 这些属性应该是ImageSource类型的。在此处查看如何定义依赖项属性:http: //msdn.microsoft.com/en-us/library/ms752914.aspx#back_dependency_properties

2) Change your style to be a style for MyImageButton:

2)将您的风格更改为以下风格MyImageButton

<ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type MyControls:MyImageButton}">

3) Change ImageBrushin your style for both enabled and disabled mode to use TemplateBinding. This is how it should be for enabled mode:

3)更改ImageBrush启用和禁用模式的样式以使用TemplateBinding. 这是启用模式的方式:

<ImageBrush ImageSource="{TemplateBinding NormalImage}"  />

回答by Peregrine

Take a look at greyableimage.codeplex.com

看看greyableimage.codeplex.com

This can be used in place of a regular image control on buttons, menus, toolbars etc. It auto-generates a "greyed-out" version of the content that will be displayed when the parent control is disabled.

这可以用来代替按钮、菜单、工具栏等上的常规图像控件。它会自动生成当父控件被禁用时将显示的“变灰”版本的内容。