wpf 当由IsMouseOver和IsPressed触发时,情节提要不工作

insrf1ej  于 2023-02-05  发布在  SEO
关注(0)|答案(1)|浏览(245)

我正在做一个自定义控件。当鼠标移到它上面时,内容的不透明度会从0.5变为0.8。当鼠标按下它时,内容的不透明度会立即设置为1。
下面是我的代码:

<ControlTemplate TargetType="{x:Type local:OpacityButton}">
                    <Border x:Name="B" Background="{TemplateBinding Background}" Opacity="0.5" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                        <ContentPresenter Margin="{TemplateBinding Padding}" TextBlock.FontFamily="{TemplateBinding FontFamily}" Content="{TemplateBinding Content}" TextBlock.Foreground="{TemplateBinding Foreground}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" TextBlock.FontSize="{TemplateBinding FontSize}"></ContentPresenter>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Trigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation
                Storyboard.TargetName="B"
                Storyboard.TargetProperty="Opacity"
                To="0.8" Duration="0:0:0.3" />
                                    </Storyboard>
                                </BeginStoryboard>
                            </Trigger.EnterActions>
                            <Trigger.ExitActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation
                Storyboard.TargetName="B"
                Storyboard.TargetProperty="Opacity"
                To="0.5" Duration="0:0:0.3" />
                                    </Storyboard>
                                </BeginStoryboard>
                            </Trigger.ExitActions>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter Property="Opacity" Value="1" TargetName="B"></Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>

按下按钮时,不透明度不会发生任何变化。
很快我找到了这个解决方案:Storyboard animation not completing when triggering property changes
我将RemoveStoryboard添加到EnterActions和ExitActions,现在当鼠标悬停时,不透明度不会发生任何变化。
这似乎是因为它立即删除故事板,但不是在它完成后。
我该如何解决这个问题?

szqfcxe2

szqfcxe21#

对于VisualState来说,这是一个更好的工作:

<ControlTemplate TargetType="{x:Type local:OpacityButton}">
    <Border x:Name="B"
            Background="{TemplateBinding Background}"
            Opacity="0.5"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal">
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="B"
                                         Storyboard.TargetProperty="Opacity"
                                         To="0.5"
                                         Duration="0:0:0.3" />
                    </Storyboard>
                </VisualState>
                <VisualState Name="MouseOver">
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="B"
                                         Storyboard.TargetProperty="Opacity"
                                         To="0.8"
                                         Duration="0:0:0.3" />
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Pressed">
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="B"
                                         Storyboard.TargetProperty="Opacity"
                                         To="1"
                                         Duration="0:0:0.3" />
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <ContentPresenter Margin="{TemplateBinding Padding}"
                          TextBlock.FontFamily="{TemplateBinding FontFamily}"
                          Content="{TemplateBinding Content}"
                          TextBlock.Foreground="{TemplateBinding Foreground}"
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                          TextBlock.FontSize="{TemplateBinding FontSize}"></ContentPresenter>
    </Border>
</ControlTemplate>

您的触发器的问题是,它们中的多个同时为真-当按钮被按下时,鼠标也在它上面,所以触发器在竞争,IsMouseOver一个获胜。
但是,控件一次只能有一个VisualState,因此您可以准确地定义在每个状态下发生的事情,并且只能定义该状态。
如果你使用触发器,你可以使用MultiTrigger作为鼠标悬停状态,使条件IsMouseOver = trueIsPressed = false成立,那么当IsPressed为真时,那个触发器将运行,而另一个不会。
但是,假设您在这里对Button进行子类化,WPF已经免费提供了VisualState,所以您不妨使用它们。

相关问题