0

Say I have a shape. I've given it a Stroke and StrokeThickness and a StrokeDashArray to get the desired dashed outline. Then I animate the StrokeDashOffset via VisualStateManager to get the "Marching Ants" style animation to it. Everything works great...

Except I want the default of the shape to NOT have a StrokeDashArray and instead want to set that based on a VisualState in the VisualStateManager except unfortunately as we know I can only do a DoubleAnimation on a Property, and not a Double Collection Value like what StrokeDashArray is...

My question is, is there a clever way I could animate that value during runtime so the shape in an UnSelected State has a solid Stroke but via the 'VisualStateManager' (maybe) still supply the StrokeDashOffset on the Selected State to the same shape? Or am I better off having two separate shapes and toggling the visibility between them so that each have their own default values?

If it would help visualize with a picture or something let me know and I'll add more to the question.

4

1 回答 1

1

一种选择是为双属性设置动画并创建一个绑定到 StrokeDashArray 的新 DoubleCollection。

xml:

<UserControl x:Class="SilverlightApplication1.MainPage"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Name="UI">
<Grid DataContext="{Binding ElementName=UI}">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState x:Name="StrokeDashArrayAnimation">
                <Storyboard BeginTime="0">
                    <DoubleAnimation Duration="0:0:5"
                                     From="0"
                                     Storyboard.TargetName="UI"
                                     Storyboard.TargetProperty="StrokeValue"
                                     To="10" />
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Ellipse x:Name="lo"
             Stroke="Red"
             StrokeDashArray="{Binding StrokeArray}"
             StrokeThickness="5" />
    <Button Width="150"
            Height="49"
            Margin="29,65,0,0"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            Click="Button_Click_1"
            Content="Start" />
</Grid>

代码:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {


    public MainPage()
        {
            InitializeComponent();
        }

        public double StrokeValue
        {
            get { return (double)GetValue(StrokeValueProperty); }
            set { SetValue(StrokeValueProperty, value); }
        }

        public static readonly DependencyProperty StrokeValueProperty =
            DependencyProperty.Register("StrokeValue", typeof(double), typeof(MainPage),
            new PropertyMetadata(0.0, OnStrokeValueChanged));

        private static void OnStrokeValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var page = d as MainPage;
            if (page != null) page.StrokeArray = new DoubleCollection { (double)e.NewValue, 1 };
        }

        public DoubleCollection StrokeArray
        {
            get { return (DoubleCollection)GetValue(StrokeArrayProperty); }
            set { SetValue(StrokeArrayProperty, value); }
        }

        public static readonly DependencyProperty StrokeArrayProperty =
            DependencyProperty.Register("StrokeArray", typeof(DoubleCollection), typeof(MainPage)
            , new PropertyMetadata(new DoubleCollection { 0, 1 }));


        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            VisualStateManager.GoToState(this, "StrokeDashArrayAnimation", false);
        }
    }
}
于 2013-10-08T05:22:40.197 回答