2

In my XAML I have the following:

<DataTemplate x:Key="ItemTemplate">
        <DockPanel Width="Auto">
            <Button Click="SelectMovie_Click" DockPanel.Dock="Top">
                <Button.Template>
                    <ControlTemplate >
                        <Image Source="{Binding image}"/>
                    </ControlTemplate>
                </Button.Template>                   
                <Button.Triggers>
                    <EventTrigger RoutedEvent="Button.Click">
                        <BeginStoryboard>
                            <Storyboard>
                                <local:GridLengthAnimation
                                    Storyboard.Target="{Binding ElementName=col2}"
                                    Storyboard.TargetProperty="Width"
                                    Duration="0:0:2"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Button.Triggers>
            </Button>
            <TextBlock Text="{Binding title}" HorizontalAlignment="Center" DockPanel.Dock="Bottom"/>
        </DockPanel>
    </DataTemplate>

<Grid Grid.Row="2" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Name="col1"  Width="{Binding ElementName=root, Path=DataContext.gla.LeftGridWidth}"/>
            <ColumnDefinition Name="col2" Width="{Binding ElementName=root, Path=DataContext.gla.RightGridWidth}"/>
        </Grid.ColumnDefinitions>
         ...
         ...
</Grid>

gla is a GridLengthAnimationObject.

I am getting the above error when I try to set my Dependency Property

public class GridLengthAnimation : AnimationTimeline
{
    public override Type TargetPropertyType
    {
        get
        {
            return typeof(GridLength);
        }
    }

    protected override System.Windows.Freezable CreateInstanceCore()
    {
        return new GridLengthAnimation();
    }

    public GridLengthAnimation()
    {
        LeftGridWidth = new GridLength(7, GridUnitType.Star);
        RightGridWidth = new GridLength(0, GridUnitType.Star);
    }

    public static readonly DependencyProperty LeftGridWidthProperty = DependencyProperty.Register("LeftGridWidth", typeof(GridLength), typeof(GridLengthAnimation));
    public GridLength LeftGridWidth
    {
        get { return (GridLength)this.GetValue(LeftGridWidthProperty); }
        set { this.SetValue(LeftGridWidthProperty, value); }
    }

    public static readonly DependencyProperty RightGridWidthProperty = DependencyProperty.Register("RightGridWidth", typeof(GridLength), typeof(GridLengthAnimation));
    public GridLength RightGridWidth
    {

        get { return (GridLength)this.GetValue(RightGridWidthProperty); }
        set { this.SetValue(RightGridWidthProperty, value); }
    }

    public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
    {
        double rightGridVal = ((GridLength)GetValue(GridLengthAnimation.RightGridWidthProperty)).Value;
        double leftGridVal = ((GridLength)GetValue(GridLengthAnimation.LeftGridWidthProperty)).Value;

        RightGridWidth = rightGridVal == 0 ? new GridLength(3, GridUnitType.Star) : new GridLength(0, GridUnitType.Star);

        return RightGridWidth;
    }        
}

Error occurs here:

 RightGridWidth = rightGridVal == 0 ? new GridLength(3, GridUnitType.Star) : new GridLength(0, GridUnitType.Star);

Stack Trace

System.InvalidOperationException: Cannot set a property on object   'VideoManager.GridLengthAnimation' because it is in a read-only state.
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value,   PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue,   OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at VideoManager.GridLengthAnimation.set_RightGridWidth(GridLength value) in    c:\Users\Giri\Documents\Visual Studio   2013\Projects\VideoManager\VideoManager\GridLengthAnimation.cs:line 47
at VideoManager.GridLengthAnimation.GetCurrentValue(Object defaultOriginValue, Object    defaultDestinationValue, AnimationClock animationClock) in c:\Users\Giri\Documents\Visual Studio   2013\Projects\VideoManager\VideoManager\GridLengthAnimation.cs:line 56
A first chance exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll     

In my LeftGrid I have a number of Buttons. The LeftGrid has a default width of 7* while the RightGrid is initially set to 0* (not visible). When a Button is clicked in the LeftGrid, the RightGrid should expand to a width of 3*. This expansion of the RightGrid should be animated. Finally if the RightGrid is expanded and a button in the LeftGrid is clicked twice in succession, the RightGrid should shrink back to 0*.

4

1 回答 1

1

a 的最简单实现GridLengthAnimation如下所示。它只添加一个To属性(例如 DoubleAnimation 有),但没有FromBy属性。因此,它只能将属性从其当前值设置为指定的目标值。

public class GridLengthAnimation : AnimationTimeline
{
    public static readonly DependencyProperty ToProperty =
        DependencyProperty.Register(
            "To", typeof(GridLength), typeof(GridLengthAnimation));

    public GridLength To
    {
        get { return (GridLength)GetValue(ToProperty); }
        set { SetValue(ToProperty, value); }
    }

    public override Type TargetPropertyType
    {
        get { return typeof(GridLength); }
    }

    protected override Freezable CreateInstanceCore()
    {
        return new GridLengthAnimation();
    }

    public override object GetCurrentValue(
        object defaultOriginValue, object defaultDestinationValue,
        AnimationClock animationClock)
    {
        var from = (GridLength)defaultOriginValue;

        if (from.GridUnitType != To.GridUnitType ||
            !animationClock.CurrentProgress.HasValue)
        {
            return from;
        }

        var p = animationClock.CurrentProgress.Value;

        return new GridLength(
            (1d - p) * from.Value + p * To.Value,
            from.GridUnitType);
    }
}

你会像这样使用它:

<local:GridLengthAnimation
    Storyboard.Target="{Binding ElementName=col2}"
    Storyboard.TargetProperty="Width"
    Duration="0:0:2" To="3*"/>
于 2015-01-07T14:25:47.640 回答