按钮上运行两个命令和动画单击

时间:2015-01-10 04:43:33

标签: c# wpf animation grid

在我的应用中,我有Left GridRight Grid。最初,Left Grid完全展开(GridLength = 7*)而Right Grid不可见(Width = 0*)。

如果点击Button中的LeftGrid并且Right Grid未展开,则Right Grid应扩展为Width 3* }。

如果Right Grid已展开并且Button中的LeftGrid被连续点击两次,则RightGrid应缩减回Width { {1}}。

这些扩展/收缩应为0*

点击Animated时,必须发生三件事。

1)所选Button的{​​{1}}应存储在id的{​​{1}}中。

2)Button将设置到的Property存储在ViewModel的{​​{1}}中。这个Width负责连续两次点击案例。

3)最后,RightGrid应该运行。

我遇到了一些问题:

1)如何将两个Property绑定到一个ViewModel

Command

这是不允许的。

我一直在看这篇文章(http://www.codeproject.com/Articles/25808/Aggregating-WPF-Commands-with-CommandGroup)。

但是,我不确定这是否对我有用,因为我在Animation中定义了Commands

2)我正在使用自定义Button动画类,因为我需要<Button DockPanel.Dock="Top" Command="{Binding DataContext.SetSelectedItemCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding id}" Command="{Binding ElementName=root, Path=DataContext.ChangeRightGridWidthCommand}" > 用于Commands

ViewModel

我打算在GridLength

中使用这样的内容
*

我应该将上述Widths代码放在:

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)
    {
         return new GridLength(To.Value,
            GridUnitType.Star);
    }
}

如果是,我的XAML<proj:GridLengthAnimation Storyboard.TargetName="rightGrid" Storyboard.TargetProperty="Width" To="RightGridWidth" Duration="0:0:2" /> <Grid.ColumnDefinitions> <ColumnDefinition Name="leftGrid" Width="7*"/> <ColumnDefinition Name="rightGrid" Width="{Binding RightGridWidth}"/> </Grid.ColumnDefinitions> 会先运行吗?我需要先运行XAML,因为只有在 <EventTrigger RoutedEvent="Button.Click"> 运行时才能正确设置Commands值。

我很困惑如何将所有这些放在一起。

非常感谢任何帮助/建议!!

1 个答案:

答案 0 :(得分:0)

使用已有的内容快速而肮脏,即运行动画的EventTrigger。

RightGridWidth属性(包含更改通知)添加到您的视图模型中:

public GridLength RightGridWidth
{
    get { return rightGridWidth; }
    set
    {
        rightGridWidth = value;
        OnPropertyChanged("RightGridWidth");
    }
}

SetSelectedItemCommand的执行处理程序中切换属性值:

if (RightGridWidth.Value == 0d)
{
    RightGridWidth = new GridLength(3d, GridUnitType.Star);
}
else
{
    RightGridWidth = new GridLength(0d, GridUnitType.Star);
}

Click EventTrigger:

中运行动画
<Button Content="Click" Command="{Binding SetSelectedItemCommand}">
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <BeginStoryboard>
                <Storyboard>
                    <local:GridLengthAnimation
                        Storyboard.Target="{Binding ElementName=col2}"
                        Storyboard.TargetProperty="Width"
                        Duration="0:0:1" To="{Binding RightGridWidth}"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

最后,使用动画GetCurrentValue的工作实现,该实现必须返回一个取决于CurrentProgress的值:

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);
}

完全不同的也许更好的方法是使用视觉状态。请参阅VisualStateManager