Подтвердить что ты не робот

Как исправить размер формы WPF - контролирует отставание и черный фон?

У меня очень простое окно WPF - единственное, что в нем - это выровненная справа кнопка. Когда я изменяю размер окна, перетаскивая левую границу, кнопка прыгает вокруг - много. Попробуйте сами, перетащите левую границу туда и обратно.

Кроме того, черный фон временно подвергается экспонированию во время изменения размеров.

В этом вопросе я задал аналогичный вопрос о Windows Forms. Единственный ответ, который я предположил, что это исправлено в WPF, однако, удивительно, это не только не исправлено, но и WPF добавляет вторую визуальную ошибку - временный черный фон.

Вот что выглядит контрольная лага; это происходит, когда я изменяю размер окна по его верхней границе (записанный с помощью камеры, потому что экранная крышка сделала его менее очевидным, сделав все медленным):

                          enter image description here

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

                    enter image description here

Я что-то делаю неправильно? Как я могу контролировать свои визуальные ощущения в одном месте во время изменения размера? Как я могу избежать черной границы?

Примечание: кнопка заканчивается в нужном месте в конце концов - она ​​только быстро перескакивает во время изменения размера.

4b9b3361

Ответ 1

Это полный рабочий код на основе 2-го решения Wieser Software Ltd.

public partial class MainView : Window
{
    public MainView()
    {
        InitializeComponent();

        //ensure win32 handle is created
        var handle = new WindowInteropHelper(this).EnsureHandle();

        //set window background
        var result = SetClassLong(handle, GCL_HBRBACKGROUND, GetSysColorBrush(COLOR_WINDOW));
    }

    public static IntPtr SetClassLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
    {
        //check for x64
        if (IntPtr.Size > 4)
            return SetClassLongPtr64(hWnd, nIndex, dwNewLong);
        else
            return new IntPtr(SetClassLongPtr32(hWnd, nIndex, unchecked((uint)dwNewLong.ToInt32())));
    }

    private const int GCL_HBRBACKGROUND = -10;
    private const int COLOR_WINDOW = 5;

    [DllImport("user32.dll", EntryPoint = "SetClassLong")]
    public static extern uint SetClassLongPtr32(IntPtr hWnd, int nIndex, uint dwNewLong);

    [DllImport("user32.dll", EntryPoint = "SetClassLongPtr")]
    public static extern IntPtr SetClassLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

    [DllImport("user32.dll")]
    static extern IntPtr GetSysColorBrush(int nIndex);
}

Ответ 2

Существует два решения, описанные здесь: http://wieser-software.blogspot.co.uk/2012/06/wpf-window-rendering-woes.html

  • Захватите WndProc и обработайте WM_ERASEBKGND и нарисуйте систему WINDOW_COLOR на фоне или другой цвет, соответствующий вашей теме приложения.
  • Вызов SetClassLong для установки фоновой кисти класса окна

    SetClassLong (Handle, GCL_HBRBACKGROUND, GetSysColorBrush (COLOR_WINDOW));

Ответ 3

Это не представляется возможным в текущих версиях WPF.

Ответ 4

Я считаю, что временный черный фон - это проблема WPF, связанная с тем, что WPF использует DirectX как механизм рендеринга, а при изменении размера окон он должен синхронизировать чертеж с системой окон. Это также может объяснить, почему кнопка уклоняется от окна при перетаскивании границы окна. Рисование неклиентской области окна намного медленнее, чем рисовать то, что внутри окна, и если вы быстро перемещаете мышь на медленном компьютере, расхождения между концом границы внутренних элементов окна, вероятно, будут более заметными.

Предположительно, это происходит только в Vista с включенным Aero, и это должно было быть исправлено в Vista SP1. Тем не менее, я просто тестировал SP2, и я все еще видел немного черного фона, но только когда Aero был включен. Моя графическая карта довольно быстрая, поэтому это было едва заметно.

Если мой анализ верен, единственный способ исправить вашу проблему - получить более быструю графическую карту или отключить Aero.

Ответ 5

Другие ответы касались того, как заполнить разные цвета фона, чтобы попытаться смягчить эффект медленного рисования WPF.

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

Визуальная ошибка в вашем первом скриншоте объясняется дополнительным уровнем проблемы изменения размера, добавленным Aero, и есть частичное обходное решение.

Я боролся с проблемой уродливого live-resize в родных приложениях Win32, и я создал круглый вопрос Question/Answer, который объединяет 10 лет сообщений о проблемах с изменением размера и предлагает некоторые новые идеи (слишком долго, чтобы вставить контент здесь в этот вопрос). Посмотри пожалуйста:

Как сгладить уродливый дрожание/мерцание/прыжки при изменении размера окон, особенно перетаскивание левой/верхней границы (Win 7-10, bg, bitblt и DWM)?