在喬的使用pinvoke和依賴屬性的評論後,我結束了這段代碼。如果代碼很長,我現在會道歉,我不應該把它放在這裏。數學在大小上並不完美。 WPF實際(高度/寬度)與Rect.Height/Width之間有很大差異,可能需要一些計算才能獲得所需的確切大小。
將其加入到MainWindow類
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int X;
public int Y;
public int Width;
public int Height;
}
public enum SpecialWindowHandles
{
HWND_TOP = 0,
HWND_BOTTOM = 1,
HWND_TOPMOST = -1,
HWND_NOTOPMOST = -2
}
[DllImport("user32.dll", SetLastError = true)]
static extern bool GetWindowRect(IntPtr hWnd, ref RECT Rect);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
public static readonly DependencyProperty WindowHeightAnimationProperty = DependencyProperty.Register("WindowHeightAnimation", typeof(double),
typeof(MainWindow), new PropertyMetadata(OnWindowHeightAnimationChanged));
private static void OnWindowHeightAnimationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var window = d as Window;
if (window != null)
{
IntPtr handle = new WindowInteropHelper(window).Handle;
var rect = new RECT();
if (GetWindowRect(handle, ref rect))
{
rect.X = (int)window.Left;
rect.Y = (int)window.Top;
rect.Width = (int)window.ActualWidth;
rect.Height = (int)(double)e.NewValue; // double casting from object to double to int
SetWindowPos(handle, new IntPtr((int)SpecialWindowHandles.HWND_TOP), rect.X, rect.Y, rect.Width, rect.Height, (uint)SWP.SHOWWINDOW);
}
}
}
public double WindowHeightAnimation
{
get { return (double)GetValue(WindowHeightAnimationProperty); }
set { SetValue(WindowHeightAnimationProperty, value); }
}
public static readonly DependencyProperty WindowWidthAnimationProperty = DependencyProperty.Register("WindowWidthAnimation", typeof(double),
typeof(MainWindow), new PropertyMetadata(OnWindowWidthAnimationChanged));
private static void OnWindowWidthAnimationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var window = d as Window;
if (window != null)
{
IntPtr handle = new WindowInteropHelper(window).Handle;
var rect = new RECT();
if (GetWindowRect(handle, ref rect))
{
rect.X = (int)window.Left;
rect.Y = (int) window.Top;
var width = (int)(double)e.NewValue;
rect.Width = width;
rect.Height = (int) window.ActualHeight;
SetWindowPos(handle, new IntPtr((int)SpecialWindowHandles.HWND_TOP), rect.X, rect.Y, rect.Width, rect.Height, (uint)SWP.SHOWWINDOW);
}
}
}
public double WindowWidthAnimation
{
get { return (double)GetValue(WindowWidthAnimationProperty); }
set { SetValue(WindowWidthAnimationProperty, value); }
}
private void GrowClick(object sender, RoutedEventArgs e)
{
this.AnimateWindowSize(Width+200, Height+200);
}
/// <summary>
/// SetWindowPos Flags
/// </summary>
public static class SWP
{
public static readonly int
NOSIZE = 0x0001,
NOMOVE = 0x0002,
NOZORDER = 0x0004,
NOREDRAW = 0x0008,
NOACTIVATE = 0x0010,
DRAWFRAME = 0x0020,
FRAMECHANGED = 0x0020,
SHOWWINDOW = 0x0040,
HIDEWINDOW = 0x0080,
NOCOPYBITS = 0x0100,
NOOWNERZORDER = 0x0200,
NOREPOSITION = 0x0200,
NOSENDCHANGING = 0x0400,
DEFERERASE = 0x2000,
ASYNCWINDOWPOS = 0x4000;
}
而在OP的代碼,因此我
Storyboard.SetTargetProperty(aniHeight, new PropertyPath(Window.HeightProperty));
Storyboard.SetTargetProperty(aniWidth, new PropertyPath(Window.WidthProperty));
改變高度和寬度的目標屬性
Storyboard.SetTargetProperty(aniHeight, new PropertyPath(MainWindow.WindowHeightAnimationProperty));
Storyboard.SetTargetProperty(aniWidth, new PropertyPath(MainWindow.WindowWidthAnimationProperty));
原來的答覆:
從我發現的代碼中沒有問題。當我改變將動畫添加到故事板(sb.Children.Add)實例的順序時,我得到了沒有寬度的高度動畫。
這使我相信,在第一個動畫正在發生時,其他動畫變爲無效。
我所能想到的就是讓它們一個接一個地動畫,一個動畫比另一個稍長。一旦第一個動畫完成,動畫就會變長。
var sb = new Storyboard { Duration = new Duration(new TimeSpan(0, 0, 0, 0, 300)) };
var aniWidth = new DoubleAnimationUsingKeyFrames();
var aniHeight = new DoubleAnimationUsingKeyFrames();
aniWidth.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 300));
aniHeight.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 150));
aniHeight.KeyFrames.Add(new EasingDoubleKeyFrame(target.ActualHeight, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 00))));
aniHeight.KeyFrames.Add(new EasingDoubleKeyFrame(newHeight, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 150))));
aniWidth.KeyFrames.Add(new EasingDoubleKeyFrame(target.ActualWidth, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 150))));
aniWidth.KeyFrames.Add(new EasingDoubleKeyFrame(newWidth, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 300))));
即使不使用XAML故事板,我也可以同時調整窗口的高度和寬度。
這就是我發現的......我想知道是否可能有使用並行時間線的解決方案,但我無法讓它工作。這個http://stackoverflow.com/questions/1769317/animate-window-resize-width-and-height-c-sharp-wpf?rq=1看起來像一個黑客,但也許這是使它工作的唯一途徑? –
是的,它看起來可能需要手動完成。該鏈接是一個很好的發現。 –
窗口上的這些頂級屬性中的一些有點奇怪,並且與其他WPF屬性的行爲不同,因爲它們位於Win32的邊界上。如果你想動畫他們在一起WPFy的方式來做到這一點將創建一個窗口上附加的DependencyProperty在封面p /調用支持HwndSource SetWindowPos。我沒有可用的Windows開發環境來編寫解決方案,因此將其作爲評論而不是答案。如果你在WPF 4.0之前這樣做,還有其他問題需要擔心。如果我很快有機會,我會寫一篇文章。 –