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

时间:2011-02-13 15:15:52

标签: wpf image user-controls button

我对WPF和XAML有点新,现在就学习。

我找到了一些以前开发人员的快速代码:

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

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

我想创建一个非常相似的自定义按钮,但是我希望公开两个自定义属性:NormalImage和DisabledImage。这些属性应该是字符串而不是Uri。我想使用路径来映像“apply.png”而不是“pack:// application:,,, / Resources / Apply.png”。 我想,要拥有这样的自定义属性,我需要一个具有依赖属性的UserControl吗?

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

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

也许NormalImage / DisabledImage稍后会被绑定,但这不太可能。

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

有人能指出我正确的文章或投入一些简单的代码吗?

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

3 个答案:

答案 0 :(得分:12)

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

的Xaml:

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

代码背后:

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);
            }
        }
    }
}

使用示例:

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

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

答案 1 :(得分:2)

这就是我的看法:

1)创建应继承常规MyImageButton的{​​{1}}类,并包含两个依赖项属性 - ButtonNormalImage。这些属性应为DisabledImage类型。请参阅此处如何定义依赖项属性:http://msdn.microsoft.com/en-us/library/ms752914.aspx#back_dependency_properties

2)将您的样式更改为ImageSource的样式:

MyImageButton

3)在启用和禁用模式下更改样式中的<ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type MyControls:MyImageButton}"> 以使用ImageBrush。这是启用模式的应用方式:

TemplateBinding

答案 2 :(得分:1)

查看greyableimage.codeplex.com

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