我有这种风格的按钮:
<Style TargetType="Button" x:Key="btnStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Image x:Name="img" Source="{TemplateBinding Tag}" Margin="{TemplateBinding Margin}"
Stretch="None"></Image>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="img" Property="Source" Value="{DynamicResource imgClose_P}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="img" Property="Source" Value="{DynamicResource imgClose_H}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
正如您所看到的,我将ImageSource绑定到按钮的Tag属性。 在Tag属性中,我将它绑定到存储此位图的ResourceDictionary:
<BitmapImage x:Key="imgClose_N" UriSource="..\AppImages\mainWindow\TopBanner\CloseButton_sN.png" />
这使我能够使用这个&#34; Imagebutton&#34;在整个应用程序中使用不同的背景图像和一个模板。 问题是如何使用触发器保持这种通用方法? 我想IsMouseOver触发器更改背景图像,但将其绑定到控件的某些属性,而不是在控件模板中硬编码。 怎么办呢?
答案 0 :(得分:2)
正如您已经建议的那样,将其称为“图像按钮”,您可以从Button
派生并定义一些要绑定的图像属性,例如: BackgroundImage
,MouseOverImage
等
从Button
派生的替代方法是使用attached properties设置图像并绑定到您的样式中的图像,但这些附加属性也必须在某处定义,而不是让它更简单。
以下是第一个解决方案的示例:
public class ImageButton : Button
{
public static readonly DependencyProperty NormalBackgroundImageProperty = DependencyProperty.Register(
"NormalBackgroundImage", typeof(ImageSource), typeof(ImageButton));
public static readonly DependencyProperty MouseOverBackgroundImageProperty = DependencyProperty.Register(
"MouseOverBackgroundImage", typeof(ImageSource), typeof(ImageButton));
public static readonly DependencyProperty PressedBackgroundImageProperty = DependencyProperty.Register(
"PressedBackgroundImage", typeof(ImageSource), typeof(ImageButton));
public ImageSource NormalBackgroundImage
{
get { return (ImageSource)GetValue(NormalBackgroundImageProperty); }
set { SetValue(NormalBackgroundImageProperty, value); }
}
public ImageSource MouseOverBackgroundImage
{
get { return (ImageSource)GetValue(MouseOverBackgroundImageProperty); }
set { SetValue(MouseOverBackgroundImageProperty, value); }
}
public ImageSource PressedBackgroundImage
{
get { return (ImageSource)GetValue(PressedBackgroundImageProperty); }
set { SetValue(PressedBackgroundImageProperty, value); }
}
}
以及下面的合适款式。请注意,此样式对按钮的内容也有ContentPresenter,并且它使用RelativeSource={RelativeSource TemplatedParent}
而不是TemplateBindings的常规绑定。这些是在运行时评估的。
<Style TargetType="local:ImageButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:ImageButton">
<Grid Margin="{TemplateBinding Margin}">
<Image x:Name="img" Source="{Binding NormalBackgroundImage, RelativeSource={RelativeSource TemplatedParent}}" Stretch="None"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="img" Property="Source" Value="{Binding MouseOverBackgroundImage, RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="img" Property="Source" Value="{Binding PressedBackgroundImage, RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
您必须使用包含类local
的命名空间/程序集的映射来定义或替换XAML名称空间ImageButton
。
按钮可以像这样使用:
<local:ImageButton
Margin="10"
NormalBackgroundImage="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"
PressedBackgroundImage="C:\Users\Public\Pictures\Sample Pictures\Tulips.jpg"
MouseOverBackgroundImage="C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg"
Content="Click Me"/>