【问题标题】:WPF: IsPressed trigger of ControlTemplate not workingWPF:ControlTemplate 的 IsPressed 触发器不起作用
【发布时间】:2013-11-27 09:03:06
【问题描述】:

我使用名为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());

它的样式定义如下:

<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>

除了IsPressed 之外,其他一切都很好。我永远看不到我在PushedImageSource 中设置的图像,我不知道为什么。 任何帮助都会得到帮助:)

编辑 1:

这是测试它的 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>

【问题讨论】:

  • 试试IsPressed 而不是Button.IsPressed 可能对你有用。
  • @NeelBhasin 不幸的是它没有。
  • 我可以看看你的 xaml 代码吗?
  • @NeelBhasin 上传了它...
  • 如果您删除 'TargetType="{x:Type Button}"' 或将其更改为 ImageButton 会怎样?

标签: c# wpf custom-controls controltemplate


【解决方案1】:

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

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

【讨论】:

  • 哇!好收获:) 没有考虑过这种可能性。谢谢! :)
  • 一百万年都不会猜到。谢谢。
  • 谢谢!!我永远不会想到触发器的顺序会影响他的行为。
【解决方案2】:

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

<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>

【讨论】:

  • 这个 IsPressed 触发器工作并没有太大意义,而您在问题中所做的那个没有。完全一样(在“Button.”旁边,但你说你那样尝试过,但没有用)。
  • @user2760623 你是对的。问题不在于IsPressed 本身,而在于它被添加到触发器集合中的顺序,就像@NovitchiS 建议的那样。我仍然会在这里留下这个答案,因为它确实有效,但我已将@NovitchiS 答案标记为解决方案。
猜你喜欢
  • 1970-01-01
  • 2016-12-05
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-08
相关资源
最近更新 更多