如何使我的按钮网格适合我在WPF-XAML中的六边形图像 [英] How to make my button grid fit my hexagon image in WPF-XAML

查看:65
本文介绍了如何使我的按钮网格适合我在WPF-XAML中的六边形图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

https://ibb.co/jkHJ1F - 链接到图片

我有一个六边形图片我的按钮如图所示。我想从角落边缘删除点击,只有在点击图片时才点击。我尝试了很少的解决方案,通过我的可点击网格总是平方,这就是为什么我的按钮点击区域比我的图片更大。



我尝试了什么:



https://ibb.co/jkHJ1F -link to image
I have a hexagon Image for my button as in picture. I want to remove click from corner edges, and to be clicked only when clicking on picture. I have tried few solution, by my clickable grid is always squared, and that's why my button click area is bigger then my picture.

What I have tried:

<pre lang="HTML"><ControlTemplate TargetType="{x:Type Button}">
                    <Grid x:Name="LayoutGrid"
                          SnapsToDevicePixels="true">
                        <ContentPresenter x:Name="contentPresenter"
                                          Focusable="True"
                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          RecognizesAccessKey="True"
                                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                          Margin="0"
                                          IsHitTestVisible="True"
                                          ToolTip="Button">
                            <ContentPresenter.Content>
                                <Image Source="/WpfApp3;component/Images/hexagonImage.png"
                                       Stretch="None" />
                            </ContentPresenter.Content>
                        </ContentPresenter>
                        <Label Content="Label"
                               HorizontalAlignment="Center"
                               VerticalAlignment="Center"
                               Margin="60,130,60,51"
                               Width="180"
                               Height="40"
                               HorizontalContentAlignment="Center"
                               RenderTransformOrigin="0.428,-0.075"
                               FontSize="18"
                               FontFamily="Arial Narrow"
                               IsHitTestVisible="False" />
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsDefaulted"
                                 Value="true" />
                        <Trigger Property="IsMouseOver"
                                 Value="true" />
                        <Trigger Property="IsPressed"
                                 Value="true" />
                        <Trigger Property="IsEnabled"
                                 Value="false">
                            <Setter Property="TextElement.Foreground"
                                    TargetName="contentPresenter"
                                    Value="{StaticResource Button.Disabled.Foreground}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>

推荐答案

这是我快速解决的问题。它符合剪辑要求,也可以支持多种状态 - MouseOver,MouseDown等...
Here is a quick solution that I've thrown together. It honors the clipping requirements and can also support multiple states - MouseOver, MouseDown, etc...
<Window 

    x:Class="WpfWindows.Window2"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d" WindowStartupLocation="CenterOwner"

    Title="Hex Button" Height="300" Width="300">
    <Window.Resources>
        <Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
            <Setter Property="Background" Value="Black"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid VerticalAlignment="{TemplateBinding VerticalContentAlignment}"

                              HorizontalAlignment="{TemplateBinding HorizontalAlignment}">
                            <Viewbox Height="75" Width="75">
                                <Path Data="M2,88.602540 152,2 302,88.602540 v173.215081 L152,350.410161 2,261.807621 z"

                                      Fill="RoyalBlue"/>
                            </Viewbox>

                            <ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}"

                                          HorizontalAlignment="{TemplateBinding HorizontalAlignment}"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Viewbox>
            <TextBlock Text="Window2"/>
        </Viewbox>
        <Button Grid.Row="1" Style="{StaticResource ButtonStyle}"

                Margin="10" HorizontalAlignment="Center"

                Content="BACK" Click="Back_Click"/>
    </Grid>
</Window>


这是答案我已经完成了,以防有人将来需要类似的东西。

1.我从Button获得了customControl。在里面我有2个DependencyProperties只是为了点击更改图像。







Here is answer that i've done, in case someone will need something similar in future.
1.rst i have made customControl deriving from Button. And inside i have 2 DependencyProperties just to change Image on click.



public ImageSource Image
            {
                get { return (ImageSource)GetValue(ImageProperty); }
                set { SetValue(ImageProperty, value); }
            }
           public static readonly DependencyProperty ImageProperty =
                DependencyProperty.Register("Image", typeof(ImageSource), typeof(CustomControl), 
                    new FrameworkPropertyMetadata(default(ImageSource), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    
            public ImageSource NewImage
            {
                get { return (ImageSource)GetValue(NewImageProperty); }
                set { SetValue(NewImageProperty, value); }
            }

            public static readonly DependencyProperty NewImageProperty =
                DependencyProperty.Register("NewImage", typeof(ImageSource), typeof(CustomControl),
                     new FrameworkPropertyMetadata(default(ImageSource), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));







在Generic.xaml里面我喜欢这样的结构化代码(这适用于我和我的项目)。






Inside of Generic.xaml i havse structured code like this ( This works for me and my project).

<ResourceDictionary

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="clr-namespace:wpf.core">
   

    <Style TargetType="{x:Type local:CustomControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid HorizontalAlignment="Center"
                          VerticalAlignment="Center"
                          Width="{Binding ActualWidth, ElementName=image}"
                          Height="{Binding ActualHeight, ElementName=image}">
                        
                        <Image x:Name="image"
                               IsHitTestVisible="False"
                               Stretch="None"
                               VerticalAlignment="Center"
                               HorizontalAlignment="Center">
                            <Image.Style>
                                <Style TargetType="{x:Type Image}">
                                    <Setter Property="Source"
                                            Value="{Binding Image, RelativeSource={RelativeSource TemplatedParent}}" />
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding IsPressed, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"
                                                     Value="true">
                                            <Setter Property="Source"
                                                    Value="{Binding NewImage, RelativeSource={RelativeSource TemplatedParent}}" />
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Image.Style>
                        </Image>
                        <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"

                                          Content="{TemplateBinding Content}"

                                          ContentStringFormat="{TemplateBinding ContentStringFormat}"

                                          Height="48"

                                          IsHitTestVisible="False"

                                          Margin="38.667,0,38,46.666"

                                          VerticalAlignment="Bottom"

                                          HorizontalAlignment="Center"

                                          MaxHeight="48"

                                          MaxWidth="188" />
                        <Path Data="M2,88.60254L152,2 302,88.60254 302,261.817621 152,350.410161 2,261.807621z"

                              RenderTransformOrigin="0.5,0.5"

                              Stretch="Fill"

                              Fill="Transparent"

                              Focusable="True"

                              StrokeThickness="0"

                              Margin="25.333,-24.001,25.333,-23.999"

                              VerticalAlignment="Stretch"

                              Opacity="0">
                            <Path.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform />
                                    <SkewTransform />
                                    <RotateTransform Angle="90" />
                                    <TranslateTransform />
                                </TransformGroup>
                            </Path.RenderTransform>
                        </Path>
                    </Grid>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsPressed"

                                 Value="true">
                            <Setter Property="Foreground"

                                    Value="White" />
                        </Trigger>

                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>





Trick was to make path (Hexagon) that will be exactly same as my pictures, and set that path to be clickable but transparent, and picture to be visible but not clickable, and that solve my problem, now i have fully functional Hexagon button.



Sample of code in main window, just to show purpose.





Trick was to make path (Hexagon) that will be exactly same as my pictures, and set that path to be clickable but transparent, and picture to be visible but not clickable, and that solve my problem, now i have fully functional Hexagon button.

Sample of code in main window, just to show purpose.

<Grid>
        <cc:CustomControl Image="/WpfApp3;component/Images/hexPicture1.png"

                          NewImage="/WpfApp3;component/Images/hexPicture2.png"

                          ToolTip="Button"

                          Content="Some content"

                          FontFamily="Arial narrow"

                          FontSize="18"/>
    </Grid>


这篇关于如何使我的按钮网格适合我在WPF-XAML中的六边形图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆