首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF:创建图像按钮使用XAML仅在非透明部分单击

WPF:创建图像按钮使用XAML仅在非透明部分单击
EN

Stack Overflow用户
提问于 2019-07-10 20:45:56
回答 1查看 200关注 0票数 0

好了,伙计们,我正在尝试用.png图像制作一个图像按钮,但我需要使用XAML使非透明部分成为可点击的部分。

我尝试了很多次使用自定义图像类,但这些尝试对我都不起作用。

这是我正在使用的png图像的示例。

下面是xaml中我的图像按钮的示例代码。

代码语言:javascript
复制
<Style x:Key="Home1_Unlocked" TargetType="Button">
        <Setter Property="Width" Value="611"/>
        <Setter Property="Height" Value="541"/>
        <Setter Property="ClickMode" Value="Press"/>
        <Setter Property="Focusable" Value="False"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
        <Setter Property="Margin" Value="100,50,0,0"/>
        <Setter Property="UIElement.SnapsToDevicePixels" Value="True"/>
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid Name="WholeButton" Background="Transparent">
                        <ui:MapObject x:Name="Home" Stretch="Uniform" Source="/Resources/Game/map/but1_dim.png">
                            <!--<ui:MapObject.RenderTransformOrigin>
                                <Point X="0.5" Y="0.5"/>
                            </ui:MapObject.RenderTransformOrigin>
                            <ui:MapObject.RenderTransform>
                                <ScaleTransform ScaleX="0.5" ScaleY="0.5" />
                            </ui:MapObject.RenderTransform>-->
                        </ui:MapObject>
                        <Grid Margin="0,0,0,150" HorizontalAlignment="Center" VerticalAlignment="Bottom">
                            <TextBlock Text="0 of 0 STARS" Style="{DynamicResource Riffic}" Margin="130,0,00,0" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Right" FontSize="40">
                                <TextBlock.Effect>
                                    <DropShadowEffect Color="Black"/>
                                </TextBlock.Effect>
                            </TextBlock>
                            <Image Grid.Column="0" Source="/Resources/Game/map/wmapenable.png" HorizontalAlignment="Left" Margin="10,0,0,0" Stretch="None"/>
                            <Image Grid.Column="0" Source="/Resources/Game/map/big1.png" HorizontalAlignment="Left" Margin="40,0,0,0" Stretch="None"/>
                        </Grid>
                        <ContentPresenter Name="MyContentPresenter" Content="{TemplateBinding ContentControl.Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="Home" Property="Source" Value="/Resources/Game/map/but1.png"/>
                        </Trigger>
                        <Trigger Property="ButtonBase.IsPressed" Value="True">
                            <Setter TargetName="WholeButton" Property="RenderTransform">
                                <Setter.Value>
                                    <ScaleTransform ScaleX="1.01" ScaleY="1.01" />
                                </Setter.Value>
                            </Setter>
                            <Setter TargetName="WholeButton" Property="RenderTransformOrigin">
                                <Setter.Value>
                                    <Point X="0.5" Y="0.5"/>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

下面是自定义图像类。

代码语言:javascript
复制
public class MapObject : Image
    {
        protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
        {
            var source = (BitmapSource)Source;

            // Get the pixel of the source that was hit
            var x = (int)(hitTestParameters.HitPoint.X / ActualWidth * source.PixelWidth);
            var y = (int)(hitTestParameters.HitPoint.Y / ActualHeight * source.PixelHeight);

            // Copy the single pixel into a new byte array representing RGBA
            var pixel = new byte[4];
            source.CopyPixels(new Int32Rect(x, y, 1, 1), pixel, 4, 0);

            // Check the alpha (transparency) of the pixel
            // - threshold can be adjusted from 0 to 255
            if (pixel[3] < 10)
                return null;

            return new PointHitTestResult(this, hitTestParameters.HitPoint);
        }
    }

没人能帮我做这个吗?

EN

回答 1

Stack Overflow用户

发布于 2019-07-10 22:08:39

下面是我要调查的几件事:

  • 确认检测到的像素就是您认为的像素。看起来你已经意识到了DPI的缩放,但即使这样也很容易遗漏一些东西(例如,Y轴反转,从WPF坐标到像素coordinates...).
  • whether的不正确映射,还有任何其他的东西也在处理鼠标点击。也许图像上的点击测试工作正常,但后面的按钮仍然在处理鼠标在透明区域上的点击?
  • 如果你不能让它在图像级别上工作,你可以定义一个与你的图像覆盖相同区域的几何体,并对该几何体进行点击测试。当然,如果你有很多图像,这可能不是一个合适的solution.
  • consider,无论WPF是不是合适的工具。WPF主要是一个用户界面框架。虽然你绝对可以使用它来做底层的图形,但是使用一个按钮意味着你将在默认情况下得到很多你可能不想要的UI功能:用户可以用tab键选择按钮或使用键盘提交它,视觉高亮显示,低帧速率(因为所有类型的事件都发生在你并不真正关心的背景中,但却占用了宝贵的资源),等等。我建议看看像UnityMonoGame这样的游戏框架,这两个框架都可以与C#一起使用,并将为您提供许多开箱即用的游戏特定功能,而不会像UI框架那样带来所有负担。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56971017

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档