wpf - 具有最小化动画的自定义窗口样式

标签 wpf animation styles minimize

我想拥有一个自定义的窗口,因此接下来的一些教程通过将窗口样式设置为无,然后自己添加标题栏/还原/最小化/关闭按钮来启用此功能。最小化是通过简单地处理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));
    }
}

最佳答案

经过一番实验后编辑了答案。

有两种选择:
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));
}

该解决方案有一个局限性-如果您从任务栏最小化该窗口,则该窗口不会设置动画。

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

以上两种方法都不是很好的方法,因为它们只是黑客。最大的缺点是,当您单击按钮时,您实际上可以看到边框再次出现。我想看看其他人会提出什么建议,因为我自己并不认为这是一个好答案。

关于wpf - 具有最小化动画的自定义窗口样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21418160/

相关文章:

c# - 调整大小时 WPF 窗口闪烁

wpf - 在不使用 INotifyPropertyChange 的情况下从头开始实现 MVVM?

javascript - 如何在运动路径上有效地反转 SVG (SMIL) 动画?

html - 移动Safari(12.2)应用了错误的样式

c# - 如何从UserControl1 WPF MVVM中的按钮将数据从一个UserControl1传递到UserControl2

c# - 在不同的 WPF xaml 用户控件中使用资源

html - CSS3 动画全屏

iPhone 游戏开发与 Cocos2d : how to generate a cool light effect when an entity gets hit?

react-native - 在 React Native 应用程序中使用排版命名空间的最佳方法是什么

android - 如何改变android中actionbar部分的颜色