我的最终目标是实现两个UserControls之间大小变化的动画。我尝试过的方法产生了一个主要问题。
我从包含一些基本文本和图标显示的DataTemplate开始,有一个高度设置为0的“edit”UserControl和一个编辑按钮。该编辑UserControl在一个GridRow中,其Height="Auto",因此它的高度也从0开始。按钮有一个DoubleAnimation,由按钮单击触发,将UserControl的高度从0动画到300。这一切都运作得很好。以下是一个简化的代码示例。
问题在于编辑用户控件的高度不是300像素,而且我在设计时也不知道它的高度。我尝试了以下方法,但没有成功。
我从包含一些基本文本和图标显示的DataTemplate开始,有一个高度设置为0的“edit”UserControl和一个编辑按钮。该编辑UserControl在一个GridRow中,其Height="Auto",因此它的高度也从0开始。按钮有一个DoubleAnimation,由按钮单击触发,将UserControl的高度从0动画到300。这一切都运作得很好。以下是一个简化的代码示例。
<DataTemplate x:Key="UserTemplate" DataType="{x:Type dataTypes:User}">
...
<controls:UserView Grid.Row="1" Grid.ColumnSpan="5" x:Name="EditRow"
DataContext="{Binding}" Height="0" />
<controls:UserEditor Grid.Row="2" Grid.ColumnSpan="5" x:Name="EditRow"
DataContext="{Binding}" Height="0" />
<Button Grid.Row="0" Grid.Column="4" Name="Edit" Style="{StaticResource ButtonStyle}"
ToolTip="Edit user" Click="Button_Click">
<Image Source="/SolutionName;component/Images/Edit.png" Stretch="None" />
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Name="EditRowHeightAnimation"
Storyboard.TargetName="EditRow" Storyboard.TargetProperty="Height" From="0"
To="300" Duration="00:00:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
...
</DataTemplate>
问题在于编辑用户控件的高度不是300像素,而且我在设计时也不知道它的高度。我尝试了以下方法,但没有成功。
<DoubleAnimation Name="EditRowHeightAnimation" Storyboard.TargetName="EditRow"
Storyboard.TargetProperty="Height" From="0" To="{Binding DesiredSize.Height,
ElementName=EditRow}" Duration="00:00:0.5" />
我还尝试从代码后台调用编辑UserControl的Measure()和UpdateLayout()方法。我注释了按钮单击触发器和xaml动画,并添加了一个从代码后台触发的触发器...现在这种方式有点奏效,但我始终得到相同(错误的)DesiredSize。也就是说,UserControl的高度会被动画化,但仅仅是到错误的高度。下面是按钮单击处理程序代码。
private void Button_Click(object sender, RoutedEventArgs e)
{
User currentUser = (User)CollectionViewSource.GetDefaultView(Users).CurrentItem;
ListBoxItem listBoxItem = (ListBoxItem)
(UsersListBox.ItemContainerGenerator.ContainerFromItem(currentUser));
DataTemplate itemDataTemplate = FindResource("UserTemplate") as DataTemplate;
ContentPresenter contentPresenter = listBoxItem.GetInternal<ContentPresenter>();
if (itemDataTemplate != null && contentPresenter != null)
{
UserEditor userEditor = (UserEditor)itemDataTemplate.FindName("EditRow",
contentPresenter);
userEditor.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
userEditor.UpdateLayout();
userEditor.BeginAnimation(HeightProperty, new DoubleAnimation(0,
userEditor.DesiredSize.Height, new Duration(new TimeSpan(0, 0, 1)),
FillBehavior.HoldEnd), HandoffBehavior.Compose);
}
}
我想知道如果UserControl的容器没有对其施加尺寸限制,当它的当前高度为0时,如何获取其大小?
如果有更好的方法实现我的最终目标,也欢迎分享。谢谢。