我在WPF中需要一个形状不规则的按钮。我是这样用XAML做的:
<Button Name="toggleButton" Click="toggleButton_Click" Canvas.Left="177" Canvas.Top="0">
<Button.Template>
<ControlTemplate>
<Image Source="ball.png" />
</ControlTemplate>
</Button.Template>
</Button>
我的ball.png图片是一张PNG图片,周围有一个透明区域的球。该按钮显示正确,但即使我克隆图像的透明部分,也会执行Click事件处理程序。
有没有办法使用透明PNG创建不规则按钮?
谢谢,Michal
答案 0 :(得分:11)
您可以创建一个继承自Image并覆盖HitTestCore的类,这样它就不会响应图像透明部分的命中测试,然后在模板中使用该类而不是普通图像。
这是一个例子,虽然检查透明像素的代码不是很健壮,因为它对图像源和像素格式做了一些假设。如果您已经有代码来检查透明像素,那么您应该将其插入。
public class TransparentImage
: Image
{
protected override HitTestResult HitTestCore(
PointHitTestParameters hitTestParameters)
{
// Get value of current pixel
var source = (BitmapSource)Source;
var x = (int)(hitTestParameters.HitPoint.X /
ActualWidth * source.PixelWidth);
var y = (int)(hitTestParameters.HitPoint.Y /
ActualHeight * source.PixelHeight);
var pixels = new byte[4];
source.CopyPixels(new Int32Rect(x, y, 1, 1), pixels, 4, 0);
// Check alpha channel
if (pixels[3] < 10)
{
return new PointHitTestResult(this, hitTestParameters.HitPoint);
}
else
{
return null;
}
}
protected override GeometryHitTestResult HitTestCore(
GeometryHitTestParameters hitTestParameters)
{
// Do something similar here, possibly checking every pixel within
// the hitTestParameters.HitGeometry.Bounds rectangle
return base.HitTestCore(hitTestParameters);
}
}
答案 1 :(得分:1)
米甲 我不会创建一个真正的“按钮”。只需进行混合,将图像作为图像画笔变成矩形,右键单击使其成为按钮。如果您使用Blend 4,这将在Visual State Manager中生成适当的状态。您可以将鼠标悬停,按下等,看起来像一个按钮。甚至是残疾州。
以下是一个例子:
<Window.Resources>
<Style x:Key="CrazyButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="path">
<EasingColorKeyFrame KeyTime="0" Value="#FFBEBEBE"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="path">
<EasingColorKeyFrame KeyTime="0" Value="#FF919191"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="path">
<EasingColorKeyFrame KeyTime="0" Value="#FF782B2B"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="path">
<EasingColorKeyFrame KeyTime="0" Value="#FF1D0C0C"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="path">
<EasingColorKeyFrame KeyTime="0" Value="#FF720505"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="path">
<EasingColorKeyFrame KeyTime="0" Value="#FF6E0000"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Path x:Name="path" Data="M95.5,33.499981 C71.500031,31.499967 76.5,68.5 76.5,68.5 L112.5,75.500276 107.5,92.500393 144.5,105.50048 152.5,79.500301 132.5,63.50019 154.5,54.500128 173.5,68.500225 168.5,87.500356 172.5,97.500425 185.5,96.500418 197.12084,75.753906 200.12084,44.753692 176.5,34.49999 143.5,32.499975 142.5,13.499841 130.5,28.499946 137.5,41.500036 135.5,51.500106 117.5,52.500113 99.5,54.500126 116.5,39.500022 z" Stretch="Fill" Stroke="{x:Null}">
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
</Path>
<ContentPresenter HorizontalAlignment="Right" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Top" Margin="0,24.52,18.715,0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True"/>
<Trigger Property="IsDefaulted" Value="True"/>
<Trigger Property="IsMouseOver" Value="True"/>
<Trigger Property="IsPressed" Value="True"/>
<Trigger Property="IsEnabled" Value="False"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
现在使用按钮如下:
<Button Content="This is my crazy button" Style="{DynamicResource CrazyButtonStyle}"/>
我知道这不是使用透明png作为按钮,但如果你能够将png转换为xaml,它将是一个更好的选择。