【问题标题】:Animating contents of WPF GridViewCellWPF GridViewCell 的动画内容
【发布时间】:2014-07-01 09:58:17
【问题描述】:

我有一个 WPF ListView,它的 View 属性设置为 GridView。 GridView 有两个 GridViewColumns,每个都有 CellTemplate - 第一列包含按钮,第二列包含边框。我的目标是在单击第一列中的按钮后为第二列中的边框设置动画。

我尝试了以下 XAML:

<ListView>
    <ListView.Items>
        <ListViewItem />                    
    </ListView.Items>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="First">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Button Height="25" 
                                Width="50">
                            <Button.Triggers>
                                <EventTrigger RoutedEvent="ButtonBase.Click">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="MyBorder"
                                                             Storyboard.TargetProperty="Opacity"
                                                             From="1.0"
                                                             To="0.0"                                                                    Duration="0:0:5"
                                                             AutoReverse="True"/>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </Button.Triggers>                                    
                        </Button>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Second">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Border Background="Black" 
                                Width="50"
                                Height="15"
                                Name="MyBorder"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

但是在运行时单击按钮时,会抛出 InvalidOperationException 并显示以下消息:在“System.Windows.Controls.Button”的名称范围内找不到“MyBorder”名称。

我做错了什么,正确的方法是什么? 提前致谢。

【问题讨论】:

  • 无法定位 MyBorder 元素。为了从 Button 事件触发器访问 MyBorder 元素,您应该在 button 的上下文中定义它。
  • 您必须采用另一种方法。为了实现这种功能
  • @Vikas 你的意思是没有办法使用 DataTemplates 为 GridViewRow 中的特定单元格设置动画?
  • 您可以使用附加属性来达到此目的。
  • @MikhailKarpov 您可以实现这一点,因为 pushpraj 提供了答案。

标签: wpf xaml animation gridview


【解决方案1】:

使用附加属性实现列间动画

使用这种方法,您还可以访问由于范围限制而无法访问的对象或属性

首先定义一个类来托管附加属性

namespace CSharpWPF
{
    public class AnimationHelper : DependencyObject
    {
        public static double GetOpacity(DependencyObject obj)
        {
            return (double)obj.GetValue(OpacityProperty);
        }

        public static void SetOpacity(DependencyObject obj, double value)
        {
            obj.SetValue(OpacityProperty, value);
        }

        // Using a DependencyProperty as the backing store for Opacity.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OpacityProperty =
            DependencyProperty.RegisterAttached("Opacity", typeof(double), typeof(AnimationHelper), new PropertyMetadata(1.0));

    }
}

xaml

<ListView xmlns:l="clr-namespace:CSharpWPF">
    <ListView.Items>
        <ListViewItem />
        <ListViewItem />
    </ListView.Items>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="First">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Button Height="25"
                            Width="50">
                            <Button.Triggers>
                                <EventTrigger RoutedEvent="ButtonBase.Click">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.Target="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType=ListViewItem}}"
                                                         Storyboard.TargetProperty="(l:AnimationHelper.Opacity)"
                                                         From="1.0"
                                                         To="0.0"
                                                         Duration="0:0:5"
                                                         AutoReverse="True" />
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </Button.Triggers>
                        </Button>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Second">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Border Background="Black"
                                Width="50"
                                Height="15"
                                Name="MyBorder" 
                                Opacity="{Binding (l:AnimationHelper.Opacity),RelativeSource={RelativeSource FindAncestor,AncestorType=ListViewItem}}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

我在AnimationHelper 类中使用了新创建的附加属性Opacity 来为值设置动画,并设置和获取我选择的值ListViewItem 作为宿主元素,这是两者的共同父元素。

使用资源的简单方法

<ListView>
    <ListView.Items>
        <ListViewItem />
    </ListView.Items>
    <ListView.Resources>
        <Border Background="Black"
                x:Key="MyBorder"
                Width="50"
                Height="15"
                Name="MyBorder" />
    </ListView.Resources>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="First">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Button Height="25"
                                Width="50">
                            <Button.Triggers>
                                <EventTrigger RoutedEvent="ButtonBase.Click">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.Target="{StaticResource MyBorder}"
                                                             Storyboard.TargetProperty="Opacity"
                                                             From="1.0"
                                                             To="0.0"
                                                             Duration="0:0:5"
                                                             AutoReverse="True" />
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </Button.Triggers>
                        </Button>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Second" x:Name="grid">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <ContentControl Content="{StaticResource MyBorder}" />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

我将边框放在资源中并在模板中指定为内容并使用相同的动画,

结果:外观相同,动画不透明

【讨论】:

  • 感谢您的回答,pushpraj。这段代码确实在隐藏边框方面发挥了作用。但问题是我可以(并且实际上确实)在 GridView 中有多个行,因此,由于几个原因,建议的方法不起作用。
  • 所以您只想隐藏相应的单元格,对吗?
  • 谢谢,pushpraj。我对 AttachedProperties 不太熟悉,所以我找到了另一个解决我的问题的方法。因为我在这个视图后面有一个视图模型,所以我将按钮的命令绑定到我的虚拟机的命令。该命令反过来会影响我的虚拟机的布尔属性。将 DataTrigger 添加到边框的样式并将其绑定到布尔属性,我可以根据属性更改将所需的动画添加到边框。在我的项目中,这个解决方案很合适,但总的来说它似乎有点人为。因此,我将您的帖子标记为答案,因为在一般情况下,这是一个非常好的解决方案。
  • 确实您的解决方案非常好。当您可以访问视图模型时,视图模型解决方案效果很好。然而,在模型中拥有这样的属性并不是一个理想的解决方案。当没有此类选项可用时,附加属性会有所帮助,例如。如果您要绑定到 xml、数据表等,请随时询问您是否有这种感觉。快乐编码:)
猜你喜欢
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-04
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多