【问题标题】:Custom Control tri-state ImageButton, cannot bind image sources自定义控件三态ImageButton,无法绑定图片源
【发布时间】:2012-01-22 23:26:23
【问题描述】:

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

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

    }
}

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

谢谢

【问题讨论】:

    标签: wpf binding custom-controls imagebutton


    【解决方案1】:

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

    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>
    

    【讨论】:

    • 很高兴发表一些评论以帮助其他人和我理解为什么这是一个糟糕的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    • 2021-06-05
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 2016-12-01
    相关资源
    最近更新 更多