WPF:ControlTemplate 的 IsPressed 触发器不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20237890/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 10:07:40  来源:igfitidea点击:

WPF: IsPressed trigger of ControlTemplate not working

c#wpfcustom-controlscontroltemplate

提问by Omri Btian

I use a custom control named ImageButtonto display a button with different images. ImageButtoncontains dependency properties:

我使用一个名为的自定义控件ImageButton来显示具有不同图像的按钮。ImageButton包含依赖属性:

public ImageSource DisabledImageSource
    {
        get { return (ImageSource)GetValue(DisabledImageSourceProperty); }
        set { SetValue(DisabledImageSourceProperty, value); }
    }


    public ImageSource NormalImageSource
    {
        get { return (ImageSource)GetValue(NormalImageSourceProperty); }
        set { SetValue(NormalImageSourceProperty, value); }
    }

    public ImageSource HoverImageSource
    {
        get { return (ImageSource)GetValue(HoverImageSourceProperty); }
        set { SetValue(HoverImageSourceProperty, value); }
    }

    public ImageSource PushedImageSource
    {
        get { return (ImageSource)GetValue(PushedImageSourceProperty); }
        set { SetValue(PushedImageSourceProperty, value); }
    }


    public static readonly DependencyProperty DisabledImageSourceProperty =
        DependencyProperty.Register("DisabledImageSource", typeof(ImageSource), typeof(ImageButton), new UIPropertyMetadata());


    public static readonly DependencyProperty NormalImageSourceProperty =
        DependencyProperty.Register("NormalImageSource", typeof(ImageSource), typeof(ImageButton), new UIPropertyMetadata());


    public static readonly DependencyProperty HoverImageSourceProperty =
        DependencyProperty.Register("HoverImageSource", typeof(ImageSource), typeof(ImageButton), new UIPropertyMetadata());

    public static readonly DependencyProperty PushedImageSourceProperty =
        DependencyProperty.Register("PushedImageSource", typeof(ImageSource), typeof(ImageButton), new UIPropertyMetadata());

It's style is defined as follows:

它的样式定义如下:

<Style TargetType="{x:Type local:ImageButton}">
    <Setter Property="HorizontalAlignment" Value="Left"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid>
                    <Image Name="image" Source="{Binding NormalImageSource, RelativeSource={RelativeSource TemplatedParent}}" Stretch="None" />
                </Grid>
                <ControlTemplate.Triggers>                    
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter TargetName="image" Property="Source" Value="{Binding DisabledImageSource, RelativeSource={RelativeSource TemplatedParent}}"/>
                    </Trigger>
                    <Trigger Property="Button.IsPressed" Value="True">
                        <Setter TargetName="image" Property="Source"  Value="{Binding PushedImageSource, RelativeSource={RelativeSource TemplatedParent}}"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter TargetName="image" Property="Source" Value="{Binding HoverImageSource, RelativeSource={RelativeSource TemplatedParent}}"/>
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Every thing works fine except IsPressed. I can never see the image I set in PushedImageSourceand I can't figure out why. Any help would be appriciated :)

除了IsPressed. 我永远看不到我设置的图像PushedImageSource,我不知道为什么。任何帮助都会得到帮助:)

EDIT 1:

编辑 1:

Here's the xaml code that tests it

这是测试它的 xaml 代码

<Window x:Class="SMEClient.WPF.Tester.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:is="clr-namespace:Project1.SearchBox;assembly=Project1"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/Project1;component/SearchBox/ImageButton.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <is:ImageButton NormalImageSource="C:\Users\Public\Pictures\Sample Pictures\Koala.jpg"
                            PushedImageSource="C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg"
                            HoverImageSource="C:\Users\Public\Pictures\Sample Pictures\Jellyfish.jpg"/>
        </StackPanel>
    </Grid>
</Window>

回答by Novitchi S

Your triggers are not mutual exclusive, in this case the order in which triggers are added to the Triggerscollection comes into play. Your last trigger IsMouseOveroverrides the Sourceproperty after IsPressedtrigger setts the correct image, since a button is Pressed only if the mouse is over (when using mouse of course).

您的触发器不是相互排斥的,在这种情况下,触发器添加到Triggers集合中的顺序会起作用。在触发器设置正确的图像后,您的最后一个触发器IsMouseOver会覆盖该Source属性IsPressed,因为只有在鼠标悬停时才会按下按钮(当然是在使用鼠标时)。

Try setting the IsPressedtrigger last in the Triggerscollection, and the IsPressedtrigger will be applied even though IsMouseOveris also true.

尝试IsPressedTriggers集合中最后设置触发器,IsPressed即使触发器IsMouseOver也为真,也会应用触发器。

回答by Omri Btian

OK, so I found a workaround which is kind of ugly, but it works

好的,所以我找到了一个有点难看的解决方法,但它有效

<Style TargetType="{x:Type local:ImageButton}">
    <Setter Property="HorizontalAlignment" Value="Left"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid>
                    <Image Name="Normal" Source="{Binding NormalImageSource, RelativeSource={RelativeSource TemplatedParent}}" Stretch="None" Visibility="Visible" />
                    <Image Name="Hover" Source="{Binding HoverImageSource, RelativeSource={RelativeSource TemplatedParent}}" Stretch="None" Visibility="Hidden"/>
                    <Image Name="Clicked" Source="{Binding PushedImageSource, RelativeSource={RelativeSource TemplatedParent}}" Stretch="None" Visibility="Hidden"/>
                    <Image Name="Disabled" Source="{Binding DisabledImageSource, RelativeSource={RelativeSource TemplatedParent}}" Stretch="None" Visibility="Hidden"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="Normal" Property="Visibility" Value="Hidden"/>
                        <Setter TargetName="Hover" Property="Visibility" Value="Visible"/>
                        <Setter TargetName="Clicked" Property="Visibility" Value="Hidden"/>
                        <Setter TargetName="Disabled" Property="Visibility" Value="Hidden"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter TargetName="Normal" Property="Visibility" Value="Hidden"/>
                        <Setter TargetName="Hover" Property="Visibility" Value="Hidden"/>
                        <Setter TargetName="Clicked" Property="Visibility" Value="Visible"/>
                        <Setter TargetName="Disabled" Property="Visibility" Value="Hidden"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter TargetName="Normal" Property="Visibility" Value="Hidden"/>
                        <Setter TargetName="Hover" Property="Visibility" Value="Hidden"/>
                        <Setter TargetName="Clicked" Property="Visibility" Value="Hidden"/>
                        <Setter TargetName="Disabled" Property="Visibility" Value="Visible"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>