2015-11-24 163 views
0

我想動畫一個曲線矩形,我必須將其從外部移動到實際的Window組件中,並且最好像它剛剛出現在屏幕上一樣。到目前爲止,我已經看到了在窗口內部的畫布中滾動動畫的建議。我不知道我是否真的可以讓Canvas超出實際窗口。我是不是該?那裏有更好的想法嗎?動畫矩形移動到窗口WPF

這是我的XAML,它的代碼隱藏到目前爲止。

UserMenu.xaml:

<Window x:Class="ChatClient.UserMenu" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="UserMenu" Height="350" Width="525" Icon="media/favicon.gif" Background="#FF3C3636" Foreground="{x:Null}"> 
    <Window.BorderBrush> 
     <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
      <GradientStop Color="Black" Offset="0"/> 
      <GradientStop Color="#FF6F6D95" Offset="1"/> 
     </LinearGradientBrush> 
    </Window.BorderBrush> 
    <Grid x:Name="GridBody"> 
     <Canvas Name="WindowMainCanvas"> 
      <Rectangle x:Name="Menu" Fill="#755E5E83" HorizontalAlignment="Left" Height="273" Stroke="Black" VerticalAlignment="Top" Width="446" RadiusY="27.5" RadiusX="27.5" Canvas.Left="545" Canvas.Top="23"/> 
      <Button x:Name="ChatClientOnlyButton" Content="Chat (Clients Only)" HorizontalAlignment="Left" Height="80" Margin="132,65,0,0" Style="{DynamicResource OTonButtonStyle1}" VerticalAlignment="Top" Width="259" FontFamily="Impact" FontSize="26.667" Foreground="#FF1C045B" Click="chatClientsOnlyOption" Visibility="Hidden"/> 
      <TextBlock x:Name="MenuLabel" HorizontalAlignment="Left" Height="25" Margin="231,35,0,0" TextWrapping="Wrap" Text="Menu" VerticalAlignment="Top" Width="101" FontFamily="Copperplate Gothic Light" FontSize="20" Visibility="Hidden"> 
       <TextBlock.Foreground> 
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
         <GradientStop Color="#FF0A1D5F" Offset="0.374"/> 
         <GradientStop Color="#FF6E7FB9" Offset="1"/> 
        </LinearGradientBrush> 
       </TextBlock.Foreground> 
      </TextBlock> 
      <Canvas ClipToBounds="True" Name="errorCanvas" Width="446" Height="17" Margin="36,152,35,151"> 
       <Rectangle x:Name="errorMarquee" Fill="#FF0A0A0C" HorizontalAlignment="Left" Height="17" Stroke="#FF5B1D1D" VerticalAlignment="Top" Width="446" Canvas.Left="-1" Visibility="Hidden"/> 
       <TextBlock x:Name="errorText" HorizontalAlignment="Left" Height="16" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="690" FontFamily="Copperplate Gothic Bold" FontSize="16" Foreground="#FF7E0202" Visibility="Hidden"/> 
      </Canvas> 
     </Canvas> 
    </Grid> 
</Window> 

UserMenu.xaml.cs:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Media.Imaging; 
using System.Windows.Shapes; 

namespace ChatClient 
{ 
    /// <summary> 
    /// Interaction logic for UserMenu.xaml 
    /// </summary> 
    public partial class UserMenu : Window 
    { 
     public UserMenu() 
     { 
      InitializeComponent(); 
      DoubleAnimation menuSlideInAnimation = new DoubleAnimation(); 
      menuSlideInAnimation.From = Menu.Margin.Left; 
      menuSlideInAnimation.To = 35; 

      menuSlideInAnimation.Completed += (s, doneEvent) => 
      { 
       //consider additional triggers 
      }; 
      menuSlideInAnimation.Duration = new Duration(TimeSpan.FromSeconds(7.0)); 
      errorText.BeginAnimation(Rectangle.MarginProperty, menuSlideInAnimation, HandoffBehavior.Compose); 
     } 

     private void chatClientsOnlyOption(object sender, RoutedEventArgs e) 
     { 
      MessageBox.Show("Not available just yet!"); 
     } 
    } 
} 

任何想法?

+0

哇,讓我救你一些這種矯枉過正的東西。 [這](http://stackoverflow.com/questions/22817854/xaml-grid-visibility-transition/22819145#22819145)答案是爲Silverlight,但在這種情況下它基本上是相同的東西。儘管如果你想要水平而不是垂直,你可以改變X的Y值。 –

+1

甜!我只是用Blend做了一些類似的代碼。很高興知道。謝謝! –

+0

很高興幫助KC'er的朋友 –

回答

2

這樣做很複雜,但你可以這樣做。

  1. 結束語要在邊境控制,以動畫的矩形,並 渲染它的內容圖像。

  2. 創建一個邊界的透明彈出你的窗口

  3. 外動畫彈出

  4. 關閉彈出窗口時的動畫完成內的矩形圖像。

這裏是接受邊境管制類動畫:

public class SlideInPopup 
{ 
    private Popup _popup; 

    public SlideInPopup() 
    { 

    } 

    public void SlideIn(Window parent, int heightOffset, Border animateControl, Duration duration) 
    { 
     if ((animateControl != null) && (parent != null)) 
     { 
      int controlHeight = (int)animateControl.ActualHeight; 
      int controlWidth = (int)animateControl.ActualWidth;     

      _popup = new Popup(); 

      double height = parent.Height; 
      double widthOffset = parent.Width; 
      double width = parent.Width * 2; 

      var fromMargin = new Thickness(animateControl.Margin.Left + widthOffset, 
               animateControl.Margin.Top, 
               animateControl.Margin.Right, 
               animateControl.Margin.Bottom); 

      var toMargin = animateControl.Margin; 


      Image animateImage = new Image();  
      animateImage.Name = "imgAnimate"; 
      animateImage.Margin = fromMargin; 
      animateImage.Height = controlHeight; 
      animateImage.Width = controlWidth; 
      animateImage.HorizontalAlignment = HorizontalAlignment.Left; 
      animateImage.VerticalAlignment = VerticalAlignment.Top; 
      animateImage.Source = CaptureScreen(animateControl, controlWidth, controlHeight); 

      animateControl.Visibility = Visibility.Collapsed; 
      animateControl.Height = 0; 

      Grid child = new Grid(); 
      child.Height = height; 
      child.Width = width; 
      child.Background = Brushes.Transparent; 
      child.Children.Add(animateImage); 

      var storyboard = new Storyboard(); 
      ThicknessAnimation animation = new ThicknessAnimation(fromMargin, toMargin, duration); 
      animation.AccelerationRatio = 0.8; 

      storyboard.Children.Add(animation); 

      storyboard.Completed += (s, doneEvent) => 
      { 
       _popup.IsOpen = false; 
       animateControl.Visibility = Visibility.Visible; 
       animateControl.Height = controlHeight; 
      }; 

      Storyboard.SetTarget(animation, animateImage); 
      Storyboard.SetTargetProperty(animation, new PropertyPath("(Margin)")); 

      _popup.Height = height; 
      _popup.Width = width; 
      _popup.HorizontalOffset = parent.Left; 
      _popup.VerticalOffset = parent.Top + heightOffset; 
      _popup.AllowsTransparency = true; 
      _popup.Child = child; 
      _popup.IsOpen = true; 

      child.Resources.Add("sbSlideIn", storyboard); 

      storyboard.Begin(); 
     }    
    } 

    private static BitmapSource CaptureScreen(Visual target, double dpiX, double dpiY) 
    { 
     if (target == null) 
     { 
      return null; 
     } 
     Rect bounds = VisualTreeHelper.GetDescendantBounds(target); 
     RenderTargetBitmap rtb = new RenderTargetBitmap((int)(bounds.Width * dpiX/96.0), 
                 (int)(bounds.Height * dpiY/96.0), 
                 dpiX, 
                 dpiY, 
                 PixelFormats.Pbgra32); 
     DrawingVisual dv = new DrawingVisual(); 
     using (DrawingContext ctx = dv.RenderOpen()) 
     { 
      VisualBrush vb = new VisualBrush(target); 
      ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size)); 
     } 
     rtb.Render(dv); 
     return rtb; 
    } 
} 

然後在你的主窗口的XAML你可以用一個邊境管制包裝你的矩形,並同時刪除畫布定位屬性

<Border x:Name="borderRect" Margin="35,23,0,0"> 
    <Rectangle x:Name="Menu" Fill="#755E5E83" HorizontalAlignment="Left" Height="273" Stroke="Black" VerticalAlignment="Top" Width="446" RadiusY="27.5" RadiusX="27.5"/ > 
</Border> 

然後,您可以使用此代碼啓動動畫:

+0

Phew!雖然我很欣賞這個答案,但它非常複雜。不過謝謝。我想我會按照第一個建議去做。 –