根据RenderCapability在

时间:2019-02-19 13:05:32

标签: c# wpf

我遇到一种情况,我想根据主机的渲染功能有选择地禁用某些效果。我正在使用RenderCapability.Tier来确定硬件功能,并使用静态类和依赖项属性将其公开给XAML。但是,在这种情况下,我无法弄清楚如何禁用XAML代码中的效果。

有问题的效果是附加到网格的BlurEffect:

    <Grid x:Name="contentGrid">
        <Grid.Effect>
            <BlurEffect Radius="0" />
        </Grid.Effect>
        ...
    </Grid>

我知道我可以使用触发器根据渲染层删除效果:

<Trigger Property="local:RenderCapabilityWrapper.Tier" Value="0">
  <Setter Property="Effect" Value="{x:Null}"/>
</Trigger> 

但是,模糊半径是通过另一个控件的模板中的数据触发器动画化的:

            <ControlTemplate TargetType="controls:Menu">
                <ControlTemplate.Resources>
                    <Storyboard x:Key="FadeInContent">
                        <DoubleAnimation Storyboard.TargetProperty="ScreenContent.Opacity" From="0.1" To="1" Duration="0:0:.1" />
                        <DoubleAnimation Storyboard.TargetProperty="ScreenContent.Effect.Radius" From="3" To="0" Duration="0:0:.2" />
                    </Storyboard>
                    <Storyboard x:Key="FadeOutContent">
                        <DoubleAnimation Storyboard.TargetProperty="ScreenContent.Opacity" From="1" To="0.1" Duration="0:0:.2" />
                        <DoubleAnimation Storyboard.TargetProperty="ScreenContent.Effect.Radius" From="0" To="3" Duration="0:0:.2" />
                    </Storyboard>
                </ControlTemplate.Resources>
                <ControlTemplate.Triggers>
                    <DataTrigger Binding="{Binding Path=MenuModel.IsVisible, RelativeSource={RelativeSource Self}}" Value="True">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard  Storyboard="{StaticResource FadeOutContent}" />
                        </DataTrigger.EnterActions>
                        <DataTrigger.ExitActions>
                            <BeginStoryboard  Storyboard="{StaticResource FadeInContent}" />
                </ControlTemplate.Triggers>
                ...

我还需要从情节提要中删除引用。我曾考虑过使用第二个故事板资源而不包含模糊动画(例如,FadeInContentLowQuality,FadInContentHighQuality),但是我不确定如何在MenuModel中的两个动画之间进行切换。可见数据触发了吗?

编辑1

mm8(感谢!)在评论中指出,我可以使用MultiDataTrigger来实现DataTriggers所需的效果:

                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Path=MenuModel.IsVisible, RelativeSource={RelativeSource Self}}" Value="True" />
                            <Condition Binding="{Binding Path=Tier, Source={x:Static local:RenderCapabilityWrapper.Instance}}" Value="0" />
                        </MultiDataTrigger.Conditions>
                        <MultiDataTrigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource FadeInMenu}" />
                            <BeginStoryboard  Storyboard="{StaticResource FadeOutContentLow}" />
                        </MultiDataTrigger.EnterActions>
                        <MultiDataTrigger.ExitActions>
                            <BeginStoryboard Storyboard="{StaticResource FadeOutMenu}" />
                            <BeginStoryboard  Storyboard="{StaticResource FadeInContentLow}" />
                        </MultiDataTrigger.ExitActions>
                    </MultiDataTrigger>

接下来的问题,我是否可以使用等效方法在EventTriggers中切换动画?

        <controls:PromptServiceListener>
            <controls:PromptServiceListener.Resources>
                <Storyboard x:Key="FadeOutLow">
                    <DoubleAnimation Storyboard.Target="{x:Reference rootLayout}" Storyboard.TargetProperty="Opacity" From="1" To="0.5" Duration="0:0:.2" />
                </Storyboard>
                <Storyboard x:Key="FadeOutHigh">
                    <DoubleAnimation Storyboard.Target="{x:Reference rootLayout}" Storyboard.TargetProperty="Opacity" From="1" To="0.5" Duration="0:0:.2" />
                    <DoubleAnimation Storyboard.Target="{x:Reference rootLayout}" Storyboard.TargetProperty="Effect.Radius" From="0" To="3" Duration="0:0:.2" />
                </Storyboard>
            </controls:PromptServiceListener.Resources>
            <controls:PromptServiceListener.Triggers>
                <EventTrigger RoutedEvent="controls:PromptServiceListener.PromptShown">
                    <BeginStoryboard>
                        <BeginStoryboard Storyboard="{StaticResource FadeOutHigh}" />
                    </BeginStoryboard>
                </EventTrigger>
            </controls:PromptServiceListener.Triggers>
        </controls:PromptServiceListener>

编辑2

有关在事件触发器中切换动画的方法,请参见:WPF MultiDataTrigger on Tag property only firing once

1 个答案:

答案 0 :(得分:1)

您可以在两个条件下使用MultiDataTrigger;一个绑定到MenuModel.IsVisible的对象,另一个绑定到RenderCapabilityWrapper.Tier的对象,然后设置操作并根据需要使用Storyboards

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding Path=MenuModel.IsVisible, RelativeSource={RelativeSource Self}}" Value="True" />
        <Condition Binding="{Binding Path=Tier, Source={x:Static local:RenderCapabilityWrapper.Instance}}" Value="0" />
    </MultiDataTrigger.Conditions>
    <MultiDataTrigger.EnterActions>
        <BeginStoryboard Storyboard="{StaticResource FadeInMenu}" />
        <BeginStoryboard Storyboard="{StaticResource FadeOutContentLow}" />
    </MultiDataTrigger.EnterActions>
    <MultiDataTrigger.ExitActions>
        <BeginStoryboard Storyboard="{StaticResource FadeOutMenu}" />
        <BeginStoryboard  Storyboard="{StaticResource FadeInContentLow}" />
    </MultiDataTrigger.ExitActions>
</MultiDataTrigger>