Вопрос:
Я хочу создать кнопку кнопки изображения, с которой изменяется источник изображения при нажатии кнопки. Его легко создать, напрямую передав нормальные/щелкнутые значения пути изображения в триггере шаблона управления.
Но мое требование – создать универсальную кнопку изображения, которая может использоваться в нескольких местах с разными нормальными/щелчками изображениями. Так что я могу передать два источника изображения в самом управлении кнопками.
<Button x:Name=»buttonImage» local:ImageButton.NormalImage=»Images/ImgA.png» local:ImageButton.PressedImage=»Images/ImgB.png» Style=»{DynamicResource ImageButtonStyle}» />
Я пытался использовать зависимые свойства и получил нормальное изображение путем привязки пути к предку, но не смог достичь IsPressed изображения на триггере IsPressed. В приведенном ниже коде ImageButton – это класс, в котором существуют прикрепленные свойства.
<Setter Property=»Template»> <Setter.Value> <ControlTemplate TargetType=»{x:Type Button}»> <Border x:Name=»BtnBorder» BorderThickness=»1″> <Image x:Name=»ButtonImage» Source=»{Binding Path=(local:ImageButton.NormalImage), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}» Width=»16″ Height=»16″/> </Border> <ControlTemplate.Triggers> <Trigger Property=»IsPressed» Value=»true»> <Setter TargetName=»ButtonImage» Property=»Source» Value=»{Binding local:ImageButton.PressedImage, RelativeSource= {RelativeSource TemplatedParent}}» /> </Trigger> <Trigger Property=»IsMouseOver» Value=»true»> <Setter TargetName=»BtnBorder» Property=»BorderBrush» Value=»Red» /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter>
Дайте мне знать, если вы знаете лучший способ достичь этой функциональности.
Лучший ответ:
Следующий код работает для меня:
public class ImageButton : ButtonBase { private const string NormalImageSourcePropertyName = «NormalImageSource»; private const string MouseOverImageSourcePropertyName = «MouseOverImageSource»; private const string MouseOverPressedImageSourcePropertyName = «MouseOverPressedImageSource»; private const string PressedImageSourcePropertyName = «PressedImageSource»; public static readonly DependencyProperty NormalImageSourceProperty = DependencyProperty.Register(NormalImageSourcePropertyName, typeof(ImageSource), typeof(ImageButton)); public static readonly DependencyProperty MouseOverImageSourceProperty = DependencyProperty.Register(MouseOverImageSourcePropertyName, typeof(ImageSource), typeof(ImageButton)); public static readonly DependencyProperty MouseOverPressedImageSourceProperty = DependencyProperty.Register(MouseOverPressedImageSourcePropertyName, typeof(ImageSource), typeof(ImageButton)); public static readonly DependencyProperty PressedImageSourceProperty = DependencyProperty.Register(PressedImageSourcePropertyName, typeof(ImageSource), typeof(ImageButton)); static ImageButton() { DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton))); } public ImageSource NormalImageSource { get { return (ImageSource)GetValue(NormalImageSourceProperty); } set { SetValue(NormalImageSourceProperty, value); } } public ImageSource MouseOverImageSource { get { return (ImageSource)GetValue(MouseOverImageSourceProperty); } set { SetValue(MouseOverImageSourceProperty, value); } } public ImageSource MouseOverPressedImageSource { get { return (ImageSource)GetValue(MouseOverPressedImageSourceProperty); } set { SetValue(MouseOverPressedImageSourceProperty, value); } } public ImageSource PressedImageSource { get { return (ImageSource)GetValue(PressedImageSourceProperty); } set { SetValue(PressedImageSourceProperty, value); } } }
И стиль
<Style TargetType=»{x:Type local:ImageButton}»> <Setter Property=»IsTabStop» Value=»False»/> <Setter Property=»Template»> <Setter.Value> <ControlTemplate TargetType=»{x:Type local:ImageButton}»> <Image x:Name=»ButtonImage» Source=»{TemplateBinding NormalImageSource}» SnapsToDevicePixels=»True» RenderOptions.BitmapScalingMode=»NearestNeighbor»/> <ControlTemplate.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property=»IsMouseOver» Value=»True»/> <Condition Property=»IsPressed» Value=»False»/> </MultiTrigger.Conditions> <Setter TargetName=»ButtonImage» Property=»Source» Value=»{Binding Path=MouseOverImageSource, RelativeSource={RelativeSource TemplatedParent}}»/> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property=»IsMouseOver» Value=»True»/> <Condition Property=»IsPressed» Value=»True»/> </MultiTrigger.Conditions> <Setter TargetName=»ButtonImage» Property=»Source» Value=»{Binding Path=MouseOverPressedImageSource, RelativeSource={RelativeSource TemplatedParent}}»/> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property=»IsMouseOver» Value=»False»/> <Condition Property=»IsPressed» Value=»True»/> </MultiTrigger.Conditions> <Setter TargetName=»ButtonImage» Property=»Source» Value=»{Binding Path=PressedImageSource, RelativeSource={RelativeSource TemplatedParent}}»/> </MultiTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
Это немного сложнее, чем ваш вопрос, потому что он поддерживает 4 изображения, чтобы улучшить работу пользователя даже при зависании.
Пример, где я использую его:
<local:ImageButton DockPanel.Dock=»Left» x:Name=»PART_CloseButton» Height=»13″ Width=»13″ Margin=»3″ NormalImageSource=»/ICeTechControlLibrary;component/Images/exit-small.png» MouseOverImageSource=»/ICeTechControlLibrary;component/Images/exit-small-hover.png» MouseOverPressedImageSource=»/ICeTechControlLibrary;component/Images/exit-small-hover.png» PressedImageSource=»/ICeTechControlLibrary;component/Images/exit-small-hover.png» />