绑定动画属性以在ItemsControl

时间:2015-05-27 16:29:40

标签: wpf xaml data-binding

我几乎可以将整个问题纳入问题主题,但有趣的部分并不合适。因此,上述问题的棘手部分是:

我的动画不适用于点击的可视对象,而是适用于包含可视对象的ItemsControl的父容器。 所以我的问题是为数据绑定找到合适的“源”。

但首先是一些XAML: 这是我试图应用的动画(在故事板资源中):

<DoubleAnimation
                Storyboard.Target="{x:Reference ItemsControlGrid}"
                Storyboard.TargetProperty="(Canvas.Left)"
                From="0" To="{Binding Source=Tile, Path=Width}"/>

有问题的部分是动画的“To”属性。 (忽略Path = Width,它只是我知道存在于绑定源上的测试属性)。 如果我使用硬编码值,它就已经可以使用了。

“Tile”是我想要绑定到的DataTemplate控件的名称。

看起来像这样:

<DataTemplate DataType="{x:Type local:Task}">
        <Grid x:Name="Tile"  MouseDown="Task_OnClick" MinWidth="200" Background="{StaticResource TileBackground}" Margin="7" RenderTransformOrigin="0.5,0.5" >
            <Grid.Triggers>
                <EventTrigger RoutedEvent="Grid.MouseDown">
                   <BeginStoryboard Storyboard="{StaticResource AnimLeave}"></BeginStoryboard>
                </EventTrigger>
            </Grid.Triggers>
...content
        </Grid>
    </DataTemplate>

ItemsControl的结构如下:

<ScrollViewer>
    <Canvas>
        <Grid x:Name="ItemsControlGrid">
        <ItemsControl x:Name="Taskboard" >
            <ItemsControl.ItemsSource>
                <CompositeCollection>
                    <CollectionContainer Collection="{Binding Tasks, Source={x:Static ...secret}}"/>
                    <Button>
                    </Button>
                </CompositeCollection>
            </ItemsControl.ItemsSource>

据我所知WPF,这不起作用,因为动画应用于ItemsControl的父级,因此动画启动器的“绑定上下文”(视觉子“Tile”)完全丢失。

总结一下我最终想要实现的目标:

我希望动画“平铺”项目,以便在我点击它时平滑地填满整个可见的滚动查看器。我尝试通过同时调整Tile的大小来实现该效果,同时移动父网格,使得tile的中心移动到scrollviewers中心。

简而言之:我希望点击的“平铺”能够平滑地打开到平铺的“细节”视图中(显示完全不同的内容)

即使有一种完全不同/更好的方法来解决我的实际问题,我仍然想知道如何完成数据绑定。

提前致谢。我肯定会从希望即将到来的答案中再次学到很多东西。

1 个答案:

答案 0 :(得分:0)

问题是故事板是一种资源。当我在DataTemplate中声明它时,我可以使用

<DoubleAnimation
    Storyboard.Target="{x:Reference ItemsControlGrid}"
    Storyboard.TargetProperty="(Canvas.Top)"
    Duration="{StaticResource ZoomInTime}" BeginTime="{StaticResource FadeOutTime}"
    From="0" To="{Binding ElementName=Tile, TargetNullValue=0, Path=Tag.(Point.Y)}">

一个棘手的部分是“Path = Tag。(Point.Y)”。我用我的Tile标签来存储我在代码后面计算的目标位置,如下所示:

var tile = ((Grid) sender);
GeneralTransform transform = tile.TransformToAncestor(CanvasTaskboard);
tile.Tag = transform.Inverse.Transform(new Point((CanvasTaskboard.ActualWidth - tile.ActualWidth) / 2, (CanvasTaskboard.ActualHeight - tile.ActualHeight) / 2));

效果很好。动画看起来很棒。

更新: 我应该提一下,也可以通过名称在Tile上“找到”动画,并直接在代码后面设置“To”属性。