如何修复WPF表单调整大小 - 控制滞后和黑色背景?

时间:2009-09-05 09:54:35

标签: wpf

我有一个非常简单的WPF窗口 - 其中唯一的东西是右对齐按钮。当我通过拖动左边界来调整窗口大小时,按钮会跳转 - 很多。自己动手,来回拖动左边界。

此外,在调整大小时,黑色背景会暂时曝光。

this问题中,我问了一个关于Windows窗体的类似问题。我得到的唯一答案表明这是在WPF中修复的,然而,令人惊讶的是,它不仅没有修复,而且WPF还增加了第二个视觉错误 - 临时黑色背景。

这是控制滞后的样子;这种情况发生在我通过顶部边框调整窗口大小时(用相机录制,因为屏幕上限使得一切都变得缓慢):

enter image description here

黑色边框示例:在调整窗口大小时拍摄;这只是一瞬间,但它非常引人注目:

enter image description here

我做错了吗?在调整大小期间,如何让我的控件在一个地方保持可视化?我怎样才能避开黑色边框?

注意:按钮最终位于正确的位置最终 - 它只会在调整大小时短暂跳过

5 个答案:

答案 0 :(得分:10)

这是基于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);
}

答案 1 :(得分:3)

在WPF的当前版本中似乎不可能。

答案 2 :(得分:3)

这里有两种解决方案: http://wieser-software.blogspot.co.uk/2012/06/wpf-window-rendering-woes.html

  1. Hook WndProc并处理WM_ERASEBKGND并在后台绘制系统WINDOW_COLOR,或其他颜色以适合您的应用主题。
  2. 调用SetClassLong设置Window Class Background Brush

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

答案 3 :(得分:1)

我认为临时黑色背景是WPF问题,因为WPF使用DirectX作为渲染机制,当你调整窗口大小时,它必须与窗口系统同步绘图。这也可以解释为什么在拖动窗口边框时按钮与窗口错位。绘制窗口的非客户区域要慢于绘制窗口内部的内容,如果在慢速计算机上快速移动鼠标,则窗口内部的边界之间的差异可能会更明显。

据说这只发生在启用了Aero的Vista上,它应该在Vista SP1中修复。但是,我刚刚在SP2上测试过,我仍然看到了一些黑色背景,但只有在Aero启用时才会看到。我的显卡非常快,所以几乎看不出来。

如果我的分析是正确的,那么解决问题的唯一方法就是获取更快的显卡或关闭Aero。

答案 4 :(得分:0)

其他答案已解决如何填充不同的背景色以尝试减轻WPF慢速绘制的影响。

我无法提供任何魔术来加快WPF的速度,但是我可以提供一些有关黑色来源的信息。

第一个屏幕截图中的视觉错误是由于Aero额外增加了一层尺寸调整问题,并且存在部分解决方法。

我正在本机Win32应用程序中处理丑陋的实时调整大小问题,我创建了一个综述问题/答案,汇集了10年有关调整大小问题的帖子,并提供了一些新见解(时间太长,无法在此处粘贴内容)题)。请参阅:

How to smooth ugly jitter/flicker/jumping when resizing windows, especially dragging left/top border (Win 7-10; bg, bitblt and DWM)?