Как создать простую кнопку WPF UserControl с пользовательскими включенными / отключенными изображениями? - PullRequest
8 голосов
/ 13 февраля 2011

Я немного новичок в 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>

По сути, это просто шаблон для кнопки с базовым эффектом наведения мыши и изображения для отключенного состояния, связанного с тегом (кажется уродливым решением).

Я хочу создать пользовательскую кнопку, которая работает примерно так же, но я хочу предоставить два пользовательских свойства: NormalImage и DisabledImage. Эти свойства должны иметь тип string, а не 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 ]

12 голосов
/ 13 февраля 2011

Вы также можете использовать 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, вы можете изменить его; также я установил фиксированный размер на внутренней кнопке, котораяВы можете захотеть удалить, просто убедитесь, что установили размер где-то, так как я думаю, что он не будет использовать пробел вообще, если вы этого не сделаете.)

2 голосов
/ 13 февраля 2011

Вот как я это вижу:

1) Создайте свой класс MyImageButton, который должен наследовать обычный Button и включать два свойства зависимости - NormalImage и DisabledImage. Эти свойства должны быть типа ImageSource. Смотрите здесь, как определить свойства зависимости: http://msdn.microsoft.com/en-us/library/ms752914.aspx#back_dependency_properties

2) Измените свой стиль на стиль MyImageButton:

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

3) Измените ImageBrush в своем стиле для включенного и отключенного режима, чтобы использовать TemplateBinding. Вот как это должно быть для включенного режима:

<ImageBrush ImageSource="{TemplateBinding NormalImage}"  />
1 голос
/ 10 октября 2011

Взгляните на greyableimage.codeplex.com

Это можно использовать вместо обычного элемента управления изображениями на кнопках, меню, панелях инструментов и т. Д. Он автоматически генерирует «серый»-out "версия содержимого, которая будет отображаться, когда родительский элемент управления отключен.

...