Статьи

Элемент управления ButtonImage Windows Phone, поддерживающий нажатые и отключенные состояния

Вступление

В сообществе Windows Phone есть много примеров создания кнопки только с изображением. Мы можем достичь этого результата с помощью следующего кода:

<Button>
    <Image Source="MyImage.png"/>
</Button>

Проблема с предыдущим кодом — невозможность установить другое изображение, когда кнопка отключена или нажата.

Решение

Я создал класс ButtonImage, чтобы установить другое изображение для отключенного и нажатого состояний.

Если вас не интересует код класса ButtonImage , вы можете пропустить этот раздел и перейти непосредственно к разделу использования.

Класс ButtonImage имеет код XML и код C #.

Код XML

<Button x:Class="DotNetApp.ButtonImage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    IsEnabledChanged="ButtonIsEnabledChanged"
    MouseEnter="ButtonMouseEnter"
    MouseLeave="ButtonMouseLeave">

    <Image Stretch="None"
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        x:Name="image" />
</Button>

Здесь нет ничего необычного, это кнопка, на которой изображение имеет контент.

Код C #

using System;
using System.Windows;
using System.Windows.Media.Imaging;

namespace DotNetApp
{
    public partial class ButtonImage
    {
        #region Fields

        public new static readonly DependencyProperty IsEnabledProperty = DependencyProperty.Register("IsEnabled", typeof (bool), typeof (ButtonImage), null);
        public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("ImageSource", typeof (string), typeof (ButtonImage), null);
        public static readonly DependencyProperty ImagePressedSourceProperty = DependencyProperty.Register("ImagePressedSource", typeof (string), typeof (ButtonImage), null);
        public static readonly DependencyProperty ImageDisabledSourceProperty = DependencyProperty.Register("ImageDisabledSource", typeof (string), typeof (ButtonImage), null);

        private BitmapImage _image;
        private BitmapImage _imagePressed;
        private BitmapImage _imageDisabled;
        private bool _isPressed;

        #endregion

        #region Constructor

        public ButtonImage()
        {
            InitializeComponent();
        }

        #endregion

        #region Properties

        public new bool IsEnabled
        {
            get { return (bool)GetValue(IsEnabledProperty); }

            set
            {
                SetValue(IsEnabledProperty, value);

                SetImageFromState();
            }
        }

        public string ImageSource
        {
            get { return (string) GetValue(ImageSourceProperty); }

            set
            {
                SetValue(ImageSourceProperty, value);

                _image = SetImage(value);
                SetImageFromState();
            }
        }

        public string ImagePressedSource
        {
            get { return (string) GetValue(ImagePressedSourceProperty); }

            set
            {
                SetValue(ImagePressedSourceProperty, value);

                _imagePressed = SetImage(value);
                SetImageFromState();
            }
        }

        public string ImageDisabledSource
        {
            get { return (string) GetValue(ImageDisabledSourceProperty); }

            set
            {
                SetValue(ImageDisabledSourceProperty, value);

                _imageDisabled = SetImage(value);
                SetImageFromState();
            }
        }

        #endregion

        #region Event Handlers

        private void ButtonIsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageFromState();
        }

        private void ButtonMouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            _isPressed = true;

            SetImageFromState();
        }

        private void ButtonMouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            _isPressed = false;

            SetImageFromState();
        }

        #endregion

        #region Private Methods

        private static BitmapImage SetImage(string imageSource)
        {
            BitmapImage bitmapImage = null;

            if (!string.IsNullOrEmpty(imageSource))
            {
                bitmapImage = new BitmapImage(new Uri(imageSource, UriKind.RelativeOrAbsolute));
            }

            return bitmapImage;
        }

        private void SetImageFromState()
        {
            if (!IsEnabled)
            {
                image.Source = _imageDisabled;
            }
            else if (_isPressed)
            {
                image.Source = _imagePressed;
            }
            else
            {
                image.Source = _image;
            }
        }

        #endregion
    }
}

Еще раз, здесь нет ничего научного. Я загружаю изображения и на основе обработчиков событий ( ButtonIsEnabledChanged , ButtonMouseEnter и ButtonMouseLeave ) устанавливаю правильное изображение.

использование

Кнопка имеет изображение для каждого состояния:

  • Обычный

  • Прессованные

  • инвалид

Чтобы использовать элемент управления ButtonImage в своем приложении, просто выполните следующие действия:

  1. Добавьте файлы ButtonImage.xaml и ButtonImage.xml.cs в ваш проект.
  2. Добавьте к вашему проекту нормальное изображение, нажатое изображение и отключенное изображение. Если вашей кнопке не нужно нажатое изображение или отключенное изображение, указывать его не нужно.
  3. Добавьте код XML
<ButtonImageApp:ButtonImage ImageSource="/ImageNormal.png"
                                                    ImageDisabledSource="/ImageDisabled.png"
                                                    ImagePressedSource="/ImagePressed.png"
                                                    Style="{StaticResource ButtonImageStyle}"
                                                    Height="50"
                                                    Width="150" />

All the properties are important. The ImageSource, ImageDisabledSource, ImagePressedSource are the actual images that you want for each state. The Height and the Width need to be the same as the specified images.

The last piece of the puzzle is the Style property set to «{StaticResource ButtonImageStyle}». If you do not set this property, there will be an unwanted transparent area around the image and the image will be smaller. Your last step is to define the ButtonImageStyle into your project. You can add it into your page or in the App resources section. The code to copy is:

Page

<phone:PhoneApplicationPage.Resources>

    <Style x:Key="ButtonImageStyle"
            TargetType="ButtonImageApp:ButtonImage">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ButtonImageApp:ButtonImage">
                    <Grid Background="Transparent">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal" />
                                <VisualState x:Name="MouseOver" />
                                <VisualState x:Name="Pressed" />
                                <VisualState x:Name="Disabled" />
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border x:Name="ButtonBackground">
                            <ContentControl x:Name="ContentContainer"
                                            ContentTemplate="{TemplateBinding ContentTemplate}"
                                            Content="{TemplateBinding Content}" />
                        </Border>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</phone:PhoneApplicationPage.Resources>

or App

<Application.Resources>

    <Style x:Key="ButtonImageStyle"
        TargetType="ButtonImageApp:ButtonImage">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ButtonImageApp:ButtonImage">
                    <Grid Background="Transparent">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal" />
                                <VisualState x:Name="MouseOver" />
                                <VisualState x:Name="Pressed" />
                                <VisualState x:Name="Disabled" />
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border x:Name="ButtonBackground">
                            <ContentControl x:Name="ContentContainer"
                                        ContentTemplate="{TemplateBinding ContentTemplate}"
                                        Content="{TemplateBinding Content}" />
                        </Border>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</Application.Resources>

Conclusion

The ButtonImage derives from a Button so you can add a Command or the Click handler.

Download