Как восстановить анимацию по умолчанию для показа / закрытия окна при установке WindowStyle в WindowLoaded? - PullRequest
0 голосов
/ 16 мая 2019

Я пытаюсь создать окно с использованием C # и WPF со следующими свойствами XAML:

    WindowStyle="None"
    AllowsTransparency="True"

Установка этих значений удаляет все стандартные функциональные возможности окна, но я могу получить большую часть его обратно, используякласс WindowChrome выглядит следующим образом:

    <WindowChrome.WindowChrome>
        <WindowChrome CaptionHeight="25" ResizeBorderThickness="7" />
    </WindowChrome.WindowChrome>

Далее я создаю свои собственные кнопки, чтобы заменить те, которые больше не существуют в строке заголовка, и задаю их поведение:

    private void minimizeButton_Click(object sender, RoutedEventArgs e)
    {
        SystemCommands.MinimizeWindow(this);
    }

    private void closeButton_Click(object sender, RoutedEventArgs e)
    {
        SystemCommands.CloseWindow(this);
    }

    private void MaximizeButton_Click(object sender, RoutedEventArgs e)
    {
        if(WindowState == WindowState.Normal)
        {
            SystemCommands.MaximizeWindow(this);
        }
        else
        {
            SystemCommands.RestoreWindow(this);
        }
    }

Это работает, но поскольку я установил для WindowStyle значение none, все встроенные анимации Window отсутствуют.Как минимум, они включают:

  1. Затухание, действующее при первом отображении окна.
  2. Эффект минимизации (при свертывании окна с помощью кнопок или панели задач).
  3. Анимации Максимизировать / Восстановить.
  4. Анимация Закрытия при закрытии окна.

Благодаря помощи пользователя reddit draxus99, я смог восстановить и свернуть свернуть/ восстановить анимации (номера 2 и 3 в списке выше) с помощью WindowsAPI следующим образом:

    [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
    private static extern int SetWindowLong32(HandleRef hWnd, int nIndex, int dwNewLong);

    [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
    private static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, IntPtr dwNewLong);

    public IntPtr myHWND;
    public const int GWL_STYLE = -16;

    public static class WS
    {
        public static readonly long
        WS_BORDER = 0x00800000L,
        WS_CAPTION = 0x00C00000L,
        WS_CHILD = 0x40000000L,
        WS_CHILDWINDOW = 0x40000000L,
        WS_CLIPCHILDREN = 0x02000000L,
        WS_CLIPSIBLINGS = 0x04000000L,
        WS_DISABLED = 0x08000000L,
        WS_DLGFRAME = 0x00400000L,
        WS_GROUP = 0x00020000L,
        WS_HSCROLL = 0x00100000L,
        WS_ICONIC = 0x20000000L,
        WS_MAXIMIZE = 0x01000000L,
        WS_MAXIMIZEBOX = 0x00010000L,
        WS_MINIMIZE = 0x20000000L,
        WS_MINIMIZEBOX = 0x00020000L,
        WS_OVERLAPPED = 0x00000000L,
        WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
        WS_POPUP = 0x80000000L,
        WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,
        WS_SIZEBOX = 0x00040000L,
        WS_SYSMENU = 0x00080000L,
        WS_TABSTOP = 0x00010000L,
        WS_THICKFRAME = 0x00040000L,
        WS_TILED = 0x00000000L,
        WS_TILEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
        WS_VISIBLE = 0x10000000L,
        WS_VSCROLL = 0x00200000L;
    }

    public static IntPtr SetWindowLongPtr(HandleRef hWnd, int nIndex, IntPtr dwNewLong)
    {
        if (IntPtr.Size == 8)
        {
            return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
        }
        else
        {
            return new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32()));
        }
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        myHWND = new WindowInteropHelper(this).Handle;
        IntPtr myStyle = new IntPtr(WS.WS_CAPTION | WS.WS_CLIPCHILDREN | WS.WS_MINIMIZEBOX | WS.WS_MAXIMIZEBOX | WS.WS_SYSMENU | WS.WS_SIZEBOX);
        SetWindowLongPtr(new HandleRef(null, myHWND), GWL_STYLE, myStyle);
    }

Проблема заключается в том, что анимация с постепенным исчезновением, которая обычно отображается при первом открытии окна, и анимация с исчезновениемкогда окно закрыто, оба отсутствуют, поэтому окно просто появляется и исчезает при открытии или закрытии программы вместо того, чтобы показывать нормальный переход замирания.Я подозреваю, что отсутствующая анимация закрытия может быть связана с тем, что я привязываю действие нажатия кнопки закрытия к:

    SystemCommands.CloseWindow(this);

, которое может закрывать окно до того, как анимация сможет отобразиться, ноЯ понятия не имею, почему первоначальное затухание в анимации не отображается, если только мне не нужно установить стиль окна даже раньше, чем в событии Window_Loaded.

1 Ответ

0 голосов
/ 17 мая 2019

Попробуйте установить анимацию постепенного появления / исчезновения с помощью свойства Opacity, например, этого ответа вручную. что-то вроде:

<Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Duration="00:00:01" Storyboard.TargetProperty="Opacity" From="0" To="1" Completed="fadeCompleted" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...