如何获得当前高度为0的WPF UI元素的所需高度?

时间:2011-02-17 21:55:47

标签: wpf animation user-controls

我的最终目标是在两个UserControl之间设置大小变化的动画。我尝试实现这一目标的方式产生了一个主要问题。

我从一个包含一些基本文本和图标显示的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>

问题是编辑UserControl不是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);
    }
}

所以我的问题是,当它的当前高度为0时,如果它的容器没有大小限制,我怎么能得到UserControl的大小呢?

我也很高兴听到是否有更好的方法来实现我的最终目标。非常感谢提前。

2 个答案:

答案 0 :(得分:5)

您可以将您想要大小的内容放入Canvas ClipToBound="True"。然后,您可以操纵Canvas的大小,但Canvas内的内容大小将始终为其所需的完整大小。

答案 1 :(得分:3)

可能更容易将目标的LayoutTransform.ScaleY从0设置为1,因为所需的高度始终为1,无需额外控制。