自定义窗口样式,最小化动画

pas*_*man 6 wpf animation styles minimize

我想要一个自定义窗口,所以遵循一些教程,通过将窗口样式设置为none,然后自己添加标题栏/恢复/最小化/关闭按钮来启用此功能.通过简单地处理click事件并将Window-state设置为最小化来实现最小化,但是这不显示您在Windows 7上看到的最小化动画,并且只是立即隐藏窗口,当与其他窗口一起使用时感觉非常奇怪做动画,因​​为你倾向于认为应用程序正在关闭.

那么,有没有启用动画?..当您将WindowStyle更改为none时,它似乎被禁用.

编辑:测试代码

public partial class MainWindow : Window
{
    public MainWindow()
    {
        WindowStyle = WindowStyle.None;
        InitializeComponent();
    }

    [DllImport("user32.dll")]
    static extern int SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonDown(e);

        // this doesnt seem to animate
        SendMessage(new WindowInteropHelper(this).Handle, 0x0112, (IntPtr)0xF020, IntPtr.Zero);
    }

    protected override void OnMouseRightButtonDown(MouseButtonEventArgs e)
    {
        base.OnMouseRightButtonDown(e);

        WindowStyle = WindowStyle.SingleBorderWindow;
        WindowState = WindowState.Minimized;
    }

    protected override void OnActivated(EventArgs e)
    {
        base.OnActivated(e);

        Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => WindowStyle = WindowStyle.None));
    }
}
Run Code Online (Sandbox Code Playgroud)

bwi*_*ing 8

.NET的更新功能解决了此问题。离开您的WindowStyle =“ SingleBorder”或“ ThreeDBorder”离开ResizeMode =“ CanResize”

然后将其添加到xaml中

<Window>
  <WindowChrome.WindowChrome>
    <WindowChrome GlassFrameThickness="0" CornerRadius="0" CaptionHeight="0" UseAeroCaptionButtons="False" ResizeBorderThickness="7"/>
  </WindowChrome.WindowChrome>
</Window>
Run Code Online (Sandbox Code Playgroud)

该窗口将不具有任何默认边框,但仍将允许调整大小,并且在最大化时不会覆盖任务栏,它还将像以前一样显示最小化动画。

编辑

这也适用于WindowStyle =“ None”。它允许调整无边界窗口的大小,就好像它具有边界一样。它还允许您在窗口上设置AllowsTransparency =“ True”。


Fay*_*ilt 7

在尝试了一下之后编辑了答案.

有两个选项: 1.您可以在最小化和激活窗口之前更改样式:

private void Button_OnClick(object sender, RoutedEventArgs e)
{
    //change the WindowStyle to single border just before minimising it
    this.WindowStyle = WindowStyle.SingleBorderWindow;
    this.WindowState = WindowState.Minimized;
}

private void MainWindow_OnActivated(object sender, EventArgs e)
{
    //change the WindowStyle back to None, but only after the Window has been activated
    Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => WindowStyle = WindowStyle.None));
}
Run Code Online (Sandbox Code Playgroud)

此解决方案有一个限制 - 如果您从窗口最小化它,它不会为窗口设置动画.

2.通过发送带有SC_MINIMIZE参数的WM_SYSCOMMAND消息并通过挂钩到消息(HwndSource.FromHwnd(m_hWnd).AddHook(WindowProc))来更改边框样式来最小化窗口.

internal class ApiCodes
{
    public const int SC_RESTORE = 0xF120;
    public const int SC_MINIMIZE = 0xF020;
    public const int WM_SYSCOMMAND = 0x0112;
}

private IntPtr hWnd;

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);


private void Window_Loaded(object sender, RoutedEventArgs e)
{
    hWnd = new WindowInteropHelper(this).Handle;
    HwndSource.FromHwnd(hWnd).AddHook(WindowProc);
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    SendMessage(hWnd, ApiCodes.WM_SYSCOMMAND, new IntPtr(ApiCodes.SC_MINIMIZE), IntPtr.Zero);
}

private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if (msg == ApiCodes.WM_SYSCOMMAND)
    {
        if (wParam.ToInt32() == ApiCodes.SC_MINIMIZE)
        {
            WindowStyle = WindowStyle.SingleBorderWindow;
            WindowState = WindowState.Minimized;
            handled = true;
        }
        else if (wParam.ToInt32() == ApiCodes.SC_RESTORE)
        {
            WindowState = WindowState.Normal;
            WindowStyle = WindowStyle.None;
            handled = true;
        }
    }
    return IntPtr.Zero;
}
Run Code Online (Sandbox Code Playgroud)

上述方法都不是很好,因为它们只是黑客攻击.最大的缺点是,当您单击按钮时,您实际上可以看到边框重新出现.我想看看其他人提出了什么,因为我不认为这是一个很好的答案.