我想创建一个图像按钮控件,按钮单击时图像源会发生变化。通过在控件模板触发器中直接传递正常/单击的图像路径值,可以轻松创建。
但我的要求是创建一个通用图像按钮,可以在具有不同正常/点击图像的多个地方使用。这样我就可以在按钮控件中传递两个图像源。
<Button x:Name="buttonImage" local:ImageButton.NormalImage="Images/ImgA.png" local:ImageButton.PressedImage="Images/ImgB.png" Style="{DynamicResource ImageButtonStyle}" />
我尝试使用依赖附加属性并通过与祖先的路径绑定实现了正常图像,但无法在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>
如果您知道更好的方法来实现此功能,请告诉我们。
答案 0 :(得分:1)
以下代码适用于我:
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" />