#wpf #xaml #animation #storyboard #expander
Вопрос:
Я пытаюсь добавить анимацию расширителя с помощью xaml (аналогичную той, которая используется в Windows 10), где при нажатии она выводит новую информацию из-под панели расширителя (прокручивается снизу вверх). Пример того, чего я пытаюсь достичь, можно найти в Windows 10, перейдя на панель управления, Параметры питания и щелкнув расширитель рядом с «Показать дополнительные планы».
У меня есть анимация для работы, но если я установлю свойство окна SizeToContent=»Высота» (которое я в конечном итоге хочу использовать, чтобы размер окна автоматически подстраивался под его содержимое), вместо этого расширенная информация прокручивается сверху вниз! Если я вручную отрегулирую высоту окна с помощью ручки (даже всего на 1 пиксель), а затем снова нажму на расширитель, анимация будет работать так, как я хочу (снизу вверх), но затем развернутая информация прокручивается выше верхней части окна >_>
Есть какие-нибудь идеи?
xaml:
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp"
mc:Ignorable="d"
Title="MainWindow" Width="480"
SizeToContent="Height">
<StackPanel VerticalAlignment="Bottom">
<!-- --><TextBlock Margin="5 0 0 0" Height="21">TITLE</TextBlock>
<!-- First Panel -->
<StackPanel>
<!-- First Panel Style -->
<StackPanel.Resources>
<BooleanToVisibilityConverter x:Key="boolToVisibility" />
<Style TargetType="StackPanel" x:Key="StackPanelMain">
<Style.Triggers>
<EventTrigger RoutedEvent="Expander.Expanded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Height" Duration="0:0:0.25" To="160" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Expander.Collapsed">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Height" Duration="0:0:0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="5 5 0 0" />
<Setter Property="Width" Value="360" />
</Style>
</StackPanel.Resources>
<!-- First Panel Code -->
<StackPanel Style="{StaticResource StackPanelMain}" Height="21">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="5 0 0 0">First Panel</TextBlock>
<Separator Margin="5 0 5 0" Opacity="0.5" Width="360"/>
<Expander x:Name="FirstPanelExpander" />
</StackPanel>
<StackPanel Orientation="Vertical" Visibility="{Binding IsExpanded, ElementName=FirstPanelExpander, Converter={StaticResource boolToVisibility}}">
<TextBox />
<TextBox />
<TextBox />
<TextBox />
<TextBox />
</StackPanel>
</StackPanel>
</StackPanel>
<!-- Next Panel -->
<StackPanel Height="21">
<!-- Next Panel Code -->
<TextBlock Margin="5 0 0 0">Next Panel</TextBlock>
</StackPanel>
</StackPanel>
</Window>
Ответ №1:
Прежде всего, нет необходимости скрывать свое Textboxes
. Когда ваши объекты находятся внутри Expander
, они уже будут скрыты, если expander
они закрыты. Ниже приведен пример дизайна, близкого к тому, что вы хотите.
<Window.Resources>
<Style TargetType="Expander" x:Key="ExpanderMain">
<Style.Triggers>
<EventTrigger RoutedEvent="Expander.Expanded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Storyboard.TargetProperty="Height" Duration="0:0:0.25" From="30" To="160" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Expander.Collapsed">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Storyboard.TargetProperty="Height" Duration="0:0:0.25" From="160" To="30" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="5 5 0 0" />
<Setter Property="Width" Value="360" />
</Style>
</Window.Resources>
<ScrollViewer>
<StackPanel>
<Expander Name="AnimatedExpander" Style="{StaticResource ExpanderMain}">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Panel - 1" />
<Separator Width="300" Margin="5,0,0,0"/>
</StackPanel>
</Expander.Header>
<StackPanel>
<TextBox/>
<TextBox/>
<TextBox/>
<TextBox/>
<TextBox/>
</StackPanel>
</Expander>
<Expander Name="AnimatedExpander2" Style="{StaticResource ExpanderMain}">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Panel - 2" />
<Separator Width="300" Margin="5,0,0,0"/>
</StackPanel>
</Expander.Header>
<StackPanel>
<TextBox/>
<TextBox/>
<TextBox/>
<TextBox/>
<TextBox/>
</StackPanel>
</Expander>
<Expander Name="AnimatedExpander3" Style="{StaticResource ExpanderMain}">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Panel - 3" />
<Separator Width="300" Margin="5,0,0,0"/>
</StackPanel>
</Expander.Header>
<StackPanel>
<TextBox/>
<TextBox/>
<TextBox/>
<TextBox/>
<TextBox/>
</StackPanel>
</Expander>
<Expander Name="AnimatedExpander4" Style="{StaticResource ExpanderMain}">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Panel - 4" />
<Separator Width="300" Margin="5,0,0,0"/>
</StackPanel>
</Expander.Header>
<StackPanel>
<TextBox/>
<TextBox/>
<TextBox/>
<TextBox/>
<TextBox/>
</StackPanel>
</Expander>
</StackPanel>
</ScrollViewer>
Комментарии:
1. спасибо за советы, но функционально ваш код делает то же самое, что и мой. поле по-прежнему загружается сверху вниз при нажатии на расширитель, и если размер окна изменяется вручную, то возникает та же проблема, что и у меня (когда поля загружаются снизу вверх, но загружаются за пределами окна и делают расширитель и первые несколько верхних полей недоступными) 😮
2. Извините, я неправильно понял. Я исправил это выше для вас. Когда он заключает свои расширители в ScrollViewer, область ScrollViewer будет открываться и закрываться в соответствии с содержимым страницы.
3. Что он делает то же самое? Вы буквально скопировали весь код?
4. Я предполагаю, что вы берете один из расширителей и устанавливаете его на
VerticalAlignment="Bottom"
. В этом случае делается отверстие вверх. Я не думаю, что вы привелиVerticalAlignment="Bottom"
пример дизайна на странице, о которой говорите. Есть расширители, выстроенные один за другим.5. Потянув экран прокрутки вниз, когда расширители будут открыты, вы получите тот же пример дизайна. Вот как это выглядит в представлении, когда средство просмотра прокрутки опускается после открытия расширителя.