Каков наилучший способ сдвинуть панель в WPF?

У меня есть довольно простой UserControl, который я сделал (извините за мой Xaml, я только изучаю WPF), и я хочу сдвинуть его с экрана. Для этого я анимирую преобразование перевода (я также пытался сделать Panel дочерним элементом холста и анимировать позицию X с теми же результатами), но панель движется очень рывками, даже на довольно быстром новом компьютере. Как лучше всего скользить внутрь и наружу (желательно с помощью KeySplines, чтобы он двигался по инерции), не получая рывков. У меня всего 8 кнопок на панели, поэтому я не думал, что это будет слишком большой проблемой.

Вот Xaml, который я использую, он отлично работает в Kaxaml, но он очень дерганый и медленный (а также дерганый и медленный при запуске, скомпилированном в приложении WPF).

  <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="1002" Height="578">
     <UserControl.Resources>            
        <Style TargetType="Button">
           <Setter Property="Control.Padding" Value="4"/>
           <Setter Property="Control.Margin" Value="10"/>
           <Setter Property="Control.Template">
              <Setter.Value>
                 <ControlTemplate TargetType="Button">
                    <Grid Name="backgroundGrid" Width="210" Height="210" Background="#00FFFFFF">
                       <Grid.BitmapEffect>
                          <BitmapEffectGroup>
                             <DropShadowBitmapEffect x:Name="buttonDropShadow" ShadowDepth="2"/>
                             <OuterGlowBitmapEffect x:Name="buttonGlow" GlowColor="#A0FEDF00" GlowSize="0"/>
                          </BitmapEffectGroup>
                       </Grid.BitmapEffect>
                       <Border x:Name="background" Margin="1,1,1,1" CornerRadius="15">
                          <Border.Background>
                             <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                <LinearGradientBrush.GradientStops>
                                   <GradientStop Offset="0" Color="#FF0062B6"/>
                                   <GradientStop Offset="1" Color="#FF0089FE"/>
                                </LinearGradientBrush.GradientStops>
                             </LinearGradientBrush>
                          </Border.Background>
                       </Border>
                       <Border Margin="1,1,1,0" BorderBrush="#FF000000" BorderThickness="1.5" CornerRadius="15"/>
                       <ContentPresenter HorizontalAlignment="Center" Margin="{TemplateBinding Control.Padding}" 
                        VerticalAlignment="Center" Content="{TemplateBinding ContentControl.Content}" 
                        ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"/>
                    </Grid>
                 </ControlTemplate>
              </Setter.Value>
           </Setter>
        </Style>
     </UserControl.Resources>
     <Canvas>
        <Grid x:Name="Panel1" Height="578" Canvas.Left="0" Canvas.Top="0">
           <Grid.RenderTransform>
              <TransformGroup>
                 <TranslateTransform x:Name="panelTranslate" X="0" Y="0"/>
              </TransformGroup>
           </Grid.RenderTransform>
           <Grid.RowDefinitions>
              <RowDefinition Height="287"/>
              <RowDefinition Height="287"/>
           </Grid.RowDefinitions>
           <Grid.ColumnDefinitions>
              <ColumnDefinition x:Name="Panel1Col1"/>
              <ColumnDefinition x:Name="Panel1Col2"/>
              <ColumnDefinition x:Name="Panel1Col3"/>
              <ColumnDefinition x:Name="Panel1Col4"/>
     <!-- Set width to 0 to hide a column-->
           </Grid.ColumnDefinitions>
           <Button x:Name="Panel1Product1" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
              <Button.Triggers>
                 <EventTrigger RoutedEvent="Button.Click" SourceName="Panel1Product1">
                    <EventTrigger.Actions>
                       <BeginStoryboard>
                          <Storyboard>
                             <DoubleAnimation BeginTime="00:00:00.6" Duration="0:0:3" From="0" Storyboard.TargetName="panelTranslate" Storyboard.TargetProperty="X" To="-1000"/>
                          </Storyboard>
                       </BeginStoryboard>
                    </EventTrigger.Actions>
                 </EventTrigger>
              </Button.Triggers>
           </Button>
           <Button x:Name="Panel1Product2" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
           <Button x:Name="Panel1Product3" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
           <Button x:Name="Panel1Product4" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
           <Button x:Name="Panel1Product5" Grid.Column="2" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
           <Button x:Name="Panel1Product6" Grid.Column="2" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
           <Button x:Name="Panel1Product7" Grid.Column="3" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
           <Button x:Name="Panel1Product8" Grid.Column="3" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Grid>
     </Canvas>
  </UserControl>

person Kris Erickson    schedule 17.01.2009    source источник


Ответы (3)


Похоже, лучшее решение на данный момент — это использовать визуальную кисть и перемещать два статических изображения при скольжении по панелям. Нечто подобное описано в этом сообщении в блоге:

Использование анимированные навигационные страницы в приложении WPF (перешел на веб-архив, но это с 2008 года, так что никаких обещаний, если это все еще лучший метод).

person Kris Erickson    schedule 19.01.2009
comment
Привет, указанная ссылка не работает: Ошибка 404 - не найдено - person Junior Mayhé; 05.10.2009
comment
Работал на меня. Идет в JAPF - Архив блога: Использование анимированных страниц навигации в приложении WPF - person Padu Merloti; 14.01.2010
comment
@PaduMerloti Ссылка была исправлена ​​после публикации комментария Джуниора. Включение соответствующего фрагмента кода/объяснения в ответ было бы гораздо более постоянным противодействием гниению ссылок. - person Asad Saeeduddin; 29.01.2014
comment
Ссылка теперь пытается отобразиться, но бесполезна из-за фатальной ошибки в ее php-коде. - person ToolmakerSteve; 14.03.2019

Я обнаружил, что производительность анимации WPF значительно улучшилась, если не использовать BitmapEffects. Попробуйте отключить их в своем примере. Я заменил тени полупрозрачными сплошными областями с градиентной заливкой и улучшил производительность.

Я также слышал, что некоторые растровые эффекты имеют повышенную производительность в более новых версиях (может быть, 3.5 SP1?), поскольку большая часть рендеринга была перенесена на аппаратное обеспечение.

person Drew Noakes    schedule 17.01.2009

Если вы достаточно долго работаете с анимацией WPF, вы обнаружите, что элементы управления большой площади на самом деле двигаются так, как вы это называете, «рывками». У меня была эта проблема даже с крошечными кнопками, которые должны были перемещаться по экрану горизонтально, и я, конечно, отказался от перемещения чего-либо большого (например, окна).

person Dmitri Nesteruk    schedule 17.01.2009