StoryBoard自动反向绑定

时间:2016-12-09 16:46:12

标签: c# wpf storyboard

无论如何都要修改故事板的自动反转属性。我想将它绑定到控件的属性但无法找到方法......

到目前为止我的代码:

public class MyProgressBar : ProgressBar
{
    public bool IndeterminateAutoReverse
    {
        get { return (bool)GetValue(IndeterminateAutoReverseProperty); }
        set { SetValue(IndeterminateAutoReverseProperty, value); }
    }

    // DependencyProperty as the backing store for IndeterminateAutoReverse
    public static readonly DependencyProperty IndeterminateAutoReverseProperty = DependencyProperty.Register(
        "IndeterminateAutoReverse",
        typeof(bool),
        typeof(MyProgressBar),
        new PropertyMetadata(true)
    );
}

Theme \ Generic.xaml中的样式:

<Style TargetType="{x:Type local:MyProgressBar}">
        <Setter Property="Foreground" Value="#FF06B025" />
        <Setter Property="Background" Value="#FFE6E6E6" />
        <Setter Property="BorderBrush" Value="#FFBCBCBC" />
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:MyProgressBar}">
                    <Grid x:Name="TemplateRoot">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Indeterminate">
                                    <Storyboard x:Name="TheStoryBoard" RepeatBehavior="Forever" AutoReverse="{Binding IndeterminateAutoReverse, RelativeSource={RelativeSource TemplatedParent}}">
                                        <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)"
                                                                      Storyboard.TargetName="Animation">
                                            <EasingPointKeyFrame KeyTime="0" Value="-0.5,0.5" />
                                            <EasingPointKeyFrame KeyTime="0:0:1" Value="0.5,0.5" />
                                            <EasingPointKeyFrame KeyTime="0:0:2" Value="1.5,0.5" />
                                        </PointAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}" />
                        <Rectangle x:Name="PART_Track" />
                        <Grid x:Name="PART_Indicator"
                              ClipToBounds="true"
                              HorizontalAlignment="Left">
                            <Rectangle x:Name="Indicator"
                                       Fill="{TemplateBinding Foreground}" />
                            <Rectangle x:Name="Animation"
                                       Fill="{TemplateBinding Foreground}"
                                       RenderTransformOrigin="0.5,0.5">
                                <Rectangle.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform ScaleX="0.25" />
                                    </TransformGroup>
                                </Rectangle.RenderTransform>
                            </Rectangle>
                        </Grid>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsIndeterminate" Value="true">
                            <Setter Property="Visibility" TargetName="Indicator" Value="Collapsed" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

有了这个,AutoReverse总是假的......

我也尝试使用ControlTemplate触发器来改变它:

<ControlTemplate.Triggers>
    <Trigger Property="IsIndeterminate" Value="true">
        <Setter Property="Visibility" argetName="Indicator" Value="Collapsed" />
    </Trigger>
    <Trigger Property="IndeterminateAutoReverse" Value="true">
        <Setter Property="AutoReverse" TargetName="TheStoryBoard" Value="True" />
    </Trigger>
</ControlTemplate.Triggers>

但它没有编译......

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

不幸的是,不支持在ControlTemplate动画中绑定(来源:https://msdn.microsoft.com/en-us/library/ms742868.aspx#Anchor_9)。

您可以使用两种不同的状态来实现您想要的效果。这是一个工作样本:

[TemplateVisualState(Name = "IndeterminateAutoReverse", GroupName = "CommonStates")]
public class MyProgressBar : ProgressBar
{
    static MyProgressBar()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyProgressBar), new FrameworkPropertyMetadata(typeof(MyProgressBar)));
    }

    public MyProgressBar()
    {
        var isIndeterminateProperty = DependencyPropertyDescriptor.FromProperty(IsIndeterminateProperty, typeof(MyProgressBar));
        isIndeterminateProperty?.AddValueChanged(this, (s,e) => SetIndeterminateState());
    }

    public bool IndeterminateAutoReverse
    {
        get { return (bool)GetValue(IndeterminateAutoReverseProperty); }
        set { SetValue(IndeterminateAutoReverseProperty, value); }
    }

    public static readonly DependencyProperty IndeterminateAutoReverseProperty =
       DependencyProperty.Register(
           "IndeterminateAutoReverse", 
           typeof(bool), 
           typeof(MyProgressBar), 
           new PropertyMetadata(true, (o, e) => (o as MyProgressBar)?.SetIndeterminateState()));

    private void SetIndeterminateState()
    {
        if (!IsIndeterminate)
        {
            return;
        }

        VisualStateManager.GoToState(
            this, 
            IndeterminateAutoReverse ? "IndeterminateAutoReverse" : "Indeterminate", 
            true);
    }
}

Generic.xaml

<Style TargetType="{x:Type local:MyProgressBar}">
    <Setter Property="Foreground" Value="#FF06B025" />
    <Setter Property="Background" Value="#FFE6E6E6" />
    <Setter Property="BorderBrush" Value="#FFBCBCBC" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyProgressBar}">
                <Grid x:Name="TemplateRoot">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Indeterminate">
                                <Storyboard RepeatBehavior="Forever">
                                    <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)"
                                                                  Storyboard.TargetName="Animation">
                                        <EasingPointKeyFrame KeyTime="0" Value="-0.5,0.5" />
                                        <EasingPointKeyFrame KeyTime="0:0:1" Value="0.5,0.5" />
                                        <EasingPointKeyFrame KeyTime="0:0:2" Value="1.5,0.5" />
                                    </PointAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="IndeterminateAutoReverse">
                                <Storyboard AutoReverse="True" RepeatBehavior="Forever">
                                    <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)"
                                                                  Storyboard.TargetName="Animation">
                                        <EasingPointKeyFrame KeyTime="0" Value="-0.5,0.5" />
                                        <EasingPointKeyFrame KeyTime="0:0:1" Value="0.5,0.5" />
                                        <EasingPointKeyFrame KeyTime="0:0:2" Value="1.5,0.5" />
                                    </PointAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Background="{TemplateBinding Background}" />
                    <Rectangle x:Name="PART_Track" />
                    <Grid x:Name="PART_Indicator"
                          ClipToBounds="true"
                          HorizontalAlignment="Left">
                        <Rectangle x:Name="Indicator"
                                   Fill="{TemplateBinding Foreground}" />
                        <Rectangle x:Name="Animation"
                                   Fill="{TemplateBinding Foreground}"
                                   RenderTransformOrigin="0.5,0.5">
                            <Rectangle.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform ScaleX="0.25" />
                                </TransformGroup>
                            </Rectangle.RenderTransform>
                        </Rectangle>
                    </Grid>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsIndeterminate" Value="true">
                        <Setter Property="Visibility" TargetName="Indicator" Value="Collapsed" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

MainWindow.xaml

<Grid>
    <local:MyProgressBar IsIndeterminate="True" IndeterminateAutoReverse="{Binding IsChecked, ElementName=TheCheckBox}"/>
    <CheckBox x:Name="TheCheckBox" />
</Grid>