Как получить желаемую высоту элемента пользовательского интерфейса WPF с текущей высотой 0? - PullRequest
4 голосов
/ 18 февраля 2011

Моя конечная цель - анимировать изменение размера между двумя пользовательскими элементами управления. То, как я пытался добиться этого, породило одну серьезную проблему.

Я начинаю с DataTemplate, который содержит некоторый базовый текст и отображение значков, пользовательский элемент управления «edit» с высотой, установленной на 0, и кнопку редактирования. 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" />

Я также пытался вызвать Measure () и UpdateLayout () при редактировании UserControl из кода ниже. Я закомментировал триггер нажатия кнопки и анимацию 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?

Я также был бы рад узнать, есть ли лучший способ достичь моей конечной цели. Большое спасибо заранее.

Ответы [ 2 ]

6 голосов
/ 18 февраля 2011

Вы можете поместить контент нужного размера в Canvas с помощью ClipToBound="True". Затем вы можете манипулировать размером Canvas, и все же размер содержимого внутри Canvas всегда будет иметь полный желаемый размер.

3 голосов
/ 02 августа 2011

Может быть, проще анимировать LayoutTransform.ScaleY вашей цели от 0 до 1, потому что желаемая высота всегда равна 1 и никакого дополнительного контроля не требуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...