自定义控件三状态图像按钮,不能绑定图像源



我正在创建自定义控件图像按钮。目的是使按钮没有任何背景或边界,只有3个图像(正常状态,按下和鼠标悬停)。当使用它时,所有3个图像都应该有边界。我从这里得到一点代码,但源是永久的。我的代码是这样的:

Generic.xaml:

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:JoesControls">
<Style TargetType="{x:Type local:ImageButton}" x:Key="styledImageButton">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ImageButton}">
                <Grid
                    Margin="{TemplateBinding Control.Padding}"
                    HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                    VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
                    SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
                    >
                    <Image Name="Normal" Source="{TemplateBinding NormalSource}"/>
                    <Image Name="Pressed" Source="{TemplateBinding PressedSource}" Visibility="Hidden"/>
                    <Image Name="Over" Source="{TemplateBinding MouseOverSource}" Visibility="Hidden"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter TargetName="Normal" Property="Visibility" Value="Hidden"/>
                        <Setter TargetName="Pressed" Property="Visibility" Value="Visible"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter TargetName="Normal" Property="Visibility" Value="Hidden"/>
                        <Setter TargetName="Over" Property="Visibility" Value="Visible"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

和ImageButton.cs:

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 JoesControls
{
    public class ImageButton : Button
    {
        static ImageButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
        }
        #region NormalSourceProperty
        public static readonly DependencyProperty NormalSourceProperty =
            DependencyProperty.Register("NormalSource", typeof(ImageSource), typeof(ImageButton),
            new FrameworkPropertyMetadata(null,
                  FrameworkPropertyMetadataOptions.AffectsRender |
                  FrameworkPropertyMetadataOptions.AffectsParentMeasure));
        public ImageSource NormalSource
        {
            get { return (ImageSource)GetValue(NormalSourceProperty); }
            set
            {
                SetValue(NormalSourceProperty, value);
            }
        }
        #endregion // NormalSource
        #region PressedSourceProperty
    public static readonly DependencyProperty PressedSourceProperty =
        DependencyProperty.Register("PressedSource", typeof(ImageSource), typeof(ImageButton),
        new FrameworkPropertyMetadata(null,
              FrameworkPropertyMetadataOptions.AffectsRender |
              FrameworkPropertyMetadataOptions.AffectsParentMeasure));
    public ImageSource PressedSource
    {
        get
        {
            
            if (PressedSource == null || PressedSource.ToString() == String.Empty)
                SetValue(PressedSourceProperty, NormalSource);
            return (ImageSource)GetValue(PressedSourceProperty);
        }
        set
        {
            SetValue(PressedSourceProperty, value);
        }
    }
    #endregion // PressedSource
    
    #region MouseOverSourceProperty
    public static readonly DependencyProperty MouseOverSourceProperty =
        DependencyProperty.Register("MouseOverSource", typeof(ImageSource), typeof(ImageButton),
        new FrameworkPropertyMetadata(null,
              FrameworkPropertyMetadataOptions.AffectsRender |
              FrameworkPropertyMetadataOptions.AffectsParentMeasure));
    public ImageSource MouseOverSource
    {
        get
        {
            if (MouseOverSource == null || MouseOverSource.ToString() == String.Empty)
                SetValue(MouseOverSourceProperty, NormalSource);
            return (ImageSource)GetValue(MouseOverSourceProperty);
        }
        set
        {
            SetValue(MouseOverSourceProperty, value);
        }
    }
    #endregion // OverSource
    }
}

它编译没有错误,但显然不能工作。源没有绑定。我猜绑定源设置不正确,但我已经尝试了一段时间,谷歌搜索它,但我卡住了。谢谢你的帮助。

谢谢

我忘记了这个问题,尽管我已经实现了我想要的。今天我发现它没有解决,所以我很高兴与你分享解决方案:

xaml.cs文件
namespace JoesControls.ImageButton
{
//JoesControls - Controls for WPF
/// <summary>
/// Interaction logic for ImageButton.xaml
/// </summary>
public partial class ImageButton : Button, INotifyPropertyChanged
{
    public ImageButton()
    {
        InitializeComponent();
    }
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        this.Ims = NormalSource;
    }
    #region NormalSourceProperty
    public static readonly DependencyProperty NormalSourceProperty =
        DependencyProperty.Register("NormalSource", typeof(ImageSource), typeof(ImageButton),
        new FrameworkPropertyMetadata(null,
              FrameworkPropertyMetadataOptions.AffectsRender |
              FrameworkPropertyMetadataOptions.AffectsParentMeasure));
    public ImageSource NormalSource
    {
        get { return (ImageSource)GetValue(NormalSourceProperty); }
        set
        {
            SetValue(NormalSourceProperty, value);
        }
    }
    #endregion // NormalSource
    #region PressedSourceProperty
    public static readonly DependencyProperty PressedSourceProperty =
        DependencyProperty.Register("PressedSource", typeof(ImageSource), typeof(ImageButton),
        new FrameworkPropertyMetadata(null,
              FrameworkPropertyMetadataOptions.AffectsRender |
              FrameworkPropertyMetadataOptions.AffectsParentMeasure));
    public ImageSource PressedSource
    {
        get
        {
            return (ImageSource)GetValue(PressedSourceProperty);
        }
        set
        {
            SetValue(PressedSourceProperty, value);
        }
    }
    #endregion // PressedSource
    #region MouseOverSourceProperty
    public static readonly DependencyProperty MouseOverSourceProperty =
        DependencyProperty.Register("MouseOverSource", typeof(ImageSource), typeof(ImageButton),
        new FrameworkPropertyMetadata(null,
              FrameworkPropertyMetadataOptions.AffectsRender |
              FrameworkPropertyMetadataOptions.AffectsParentMeasure));
    public ImageSource MouseOverSource
    {
        get
        {
            return (ImageSource)GetValue(MouseOverSourceProperty);
        }
        set
        {
            if (value == null)
                SetValue(MouseOverSourceProperty, NormalSourceProperty);
            else
                SetValue(MouseOverSourceProperty, value);
        }
    }
    #endregion // OverSource
    private void Button_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
    {
        changeImage(MouseOverSource);
    }
    private void Button_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
    {
        changeImage(NormalSource);
    }
    private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        changeImage(PressedSource);
    }
    private void Button_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        changeImage(MouseOverSource);
    }
    private void changeImage(ImageSource newSource)
    {
        //ButtonImage.Source = newSource;
        Ims = newSource;
    }
    private ImageSource _ims;
    public ImageSource Ims
    {
        get { return _ims; }
        set
        {
            _ims = value;
            OnPropertyChanged("Ims");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

}

和xaml文件:

<Button x:Class="JoesControls.ImageButton.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"
    MouseEnter="Button_MouseEnter"
    MouseLeave="Button_MouseLeave"
    PreviewMouseDown="Button_PreviewMouseDown"
    PreviewMouseUp="Button_PreviewMouseUp"
    >
<Button.Style>
    <Style TargetType="{x:Type Button}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Image Source="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Path=Ims}"
                           Margin="{TemplateBinding Control.Padding}"
                           HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                           VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
                           SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
                           MinHeight="10"                            
                           MinWidth="10"
                            />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Button.Style>

最新更新