简体   繁体   中英

What is the best way to slide a panel in WPF?

I have a fairly simple UserControl that I have made (pardon my Xaml I am just learning WPF) and I want to slide the off the screen. To do so I am animating a translate transform (I also tried making the Panel the child of a canvas and animating the X position with the same results), but the panel moves very jerkily, even on a fairly fast new computer. What is the best way to slide in and out (preferably with KeySplines so that it moves with inertia) without getting the jerkyness. I only have 8 buttons on the panel, so I didn't think it would be too much of a problem.

Here is the Xaml I am using, it runs fine in Kaxaml, but it is very jerky and slow (as well as being jerkly and slow when run compiled in a WPF app).

  <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>

It looks like the best solution so far, is to use a Visual Brush and move two static images when sliding in and out the panels. Something similar to this is described in this blog post:

Using animated navigation pages in a WPF application (switched to web archive, but this is from 2008 so no promises if it is still the best technique).

I've found WPF performance of animations to improve significantly when not using BitmapEffect s. Try disabling them in your example. I replaced my drop shadows with semi-transparent solid regions with gradient fills and performance improved.

I've also heard that some bitmap effects have increased performance in newer versions (maybe 3.5 SP1?) as more of the rendering has been pushed to the hardware.

If you work with WPF animations long enough, you'll figure out that large-area controls do, in fact, move in a what you call 'jerky' manner. I've had this problem even with tiny buttons that needed to move horizontally on the screen, and I have certainly given up on moving anything large (eg, a window).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM