My ultimate goal is to animate the change in size between two UserControls. The way that I have attempted to achieve this has produced one major problem.
I start with a DataTemplate that contains some basic text and icon display, an 'edit' UserControl with a height set to 0 and an edit button. The edit UserControl is in a GridRow with Height="Auto", so it also starts out with a height of 0. The button has a DoubleAnimation triggered by the button click that animates the height of the UserControl from 0 to 300. This all works just fine. Here is a simplified code example.
<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>
The problem is that the edit UserControl is not 300 pixels high and I won't know what height it will be at design time. I tried the following, but it doesn't work.
<DoubleAnimation Name="EditRowHeightAnimation" Storyboard.TargetName="EditRow"
Storyboard.TargetProperty="Height" From="0" To="{Binding DesiredSize.Height,
ElementName=EditRow}" Duration="00:00:0.5" />
I have also tried calling Measure() and UpdateLayout() on the edit UserControl from code behind. I commented out the button click trigger and xaml animation and added one from code behind instead... now this kind of worked, but I always got the same (wrong) DesiredSize. That is, the UserControl height would get animated, but just to the wrong height. Here is the button click handler code.
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);
}
}
So my question is how can I get the size that a UserControl would be if its container placed no size restriction upon it, when its current height is 0?
I'd also be happy to hear if there is a better way to achieve my ultimate goal. Many thanks in advance.
You can put the content you want the size of into a Canvas
with ClipToBound="True"
. Then you can manipulate the size of the Canvas
and yet the size of the content inside the Canvas
will always be its full desired size.
Maybe it's easier to animate the LayoutTransform.ScaleY
of your target from 0 to 1, because desired height is always 1 and no extra control is needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With