我有一个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并显示以下消息:&#39; MyBorder&#39;在System.Windows.Controls.Button&#39;的名称范围内找不到名称。
我做错了什么,做正确的方法是什么? 提前谢谢。
答案 0 :(得分:0)
使用附加属性实现内部列动画
使用此方法,您还可以访问由于范围限制而无法访问的对象
首先定义一个类来托管附加属性
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>
我在Opacity
类中使用了新创建的附加属性AnimationHelper
来设置值的动画,并设置并获取我选择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>
我将边框放在资源中并在模板中指定为内容,并将其用于动画,
结果:外观相同,不透明度的动画