c# - 在 .NET 4 中最大化窗口时,窗口顶部和左侧值未正确更新

标签 c# .net wpf

我试图将一个窗口置于所有者窗口的中心。我还需要子窗口沿着所有者窗口移动。可以找到 MSDN WPF 论坛上的交叉帖子 here .

为此,我订阅了子窗口所有者的 LocationChangedSizeChanged 事件(以及 StateChanged 事件)。当这些事件被触发时,我重新计算子窗口的位置。我在子窗口的代码隐藏中执行此操作。

代码非常简单:

Top = Owner.Top + ((Owner.ActualHeight - ActualHeight) / 2);
Left = Owner.Left + ((Owner.ActualWidth - ActualWidth) / 2);

如果您编译并运行我提供的示例程序,您将看到它在主窗口保持原样并四处移动时工作。所以那部分工作。

问题出现在所有者窗口最大化时。 (最大化后,设置回正常。)因为我订阅了三个事件,所以我进入了三次重定位功能。打印出所有者数据后,我得到了不同的结果。最烦人的是,所有者窗口的 TopLeft 值已关闭。它似乎在状态更改时获得了正确的 Top 和 Left 值,但是 ActualWidthActualHeight 值是错误的。当触发 LocationChangedSizeChanged 事件时,ActualWidthActualHeight 值正常,但 Top 和 Left 值不正确。这些似乎是以前的值。怎么会这样?是什么原因造成的?对此有适当的解决方法吗?

由于相同的代码似乎在 .net 3.5 中有效,我的印象是 .net 4 中发生了一些变化。(或者我有一个奇怪的时间问题导致问题没有出现。)但是我找不到任何文档这部分的变化。

.NET 3.5:

OnOwnerLocationChanged
T: -8; L: -8; W: 640; H: 480
OnOwnerStateChanged
T: -8; L: -8; W: 640; H: 480
OnOwnerSizeChanged
T: -8; L: -8; W: 1936; H: 1066

.NET 4.0:

OnOwnerLocationChanged
T: -8; L: -8; W: 640; H: 480
OnOwnerStateChanged
T: 494; L: 33; W: 640; H: 480
OnOwnerSizeChanged
T: 494; L: 33; W: 1936; H: 1066

所以主要问题仍然存在:为什么所有者的 Top 和 Left 值不正确?

最佳答案

comment来自 Mataniko 关于 .NET 4.0 中的迁移问题是正确的。由于当 WindowState 设置为 Normal 时我的代码可以正常工作,所以我可以保留它。当 WindowStateMaximized 时,我不得不预见到一些事情。

我实现了原生 GetWindowRect()功能来实现这一点,因为它可以给我适当的尺寸。

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

// Make sure RECT is actually OUR defined struct, not the windows rect.
public static RECT GetWindowRectangle(Window window)
{
    RECT rect;
    GetWindowRect((new WindowInteropHelper(window)).Handle, out rect);

    return rect;
}

接下来,当Owner.WindowStateMaximized 时,我们使用GetWindowRectangle 函数来获取实际尺寸。我们此时不关心边界,但如果需要,可以使用 GetSystemMetrics 合并它。功能。

if (Owner.WindowState == WindowState.Maximized)
{
    var rect = GetWindowRectangle(Owner);

    Top = rect.Top + ((rect.Bottom - ActualHeight) / 2);
    Left = rect.Left + ((rect.Right - ActualWidth) / 2);
}

关于c# - 在 .NET 4 中最大化窗口时,窗口顶部和左侧值未正确更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9812756/

相关文章:

c# - await Task.Run(ioBoundOperation) 是否等于 ioBoundOperation?

.net - 为什么 String.Empty 不是常量?

c# - 等到进程不再运行或超时已过,以先发生者为准

c# - 如何在设计时从我的 WPF 应用程序获取应用程序的目录?

c# - 位数组 VS boolean []

c# - 将 NULL 传递给 COM 接口(interface)方法的 ref/out 参数

c# - 在带有服务器控件的页面上使用 LoadControl

c# - 如何在运行时在 Entity Framework Core 中真正定位表

c# - WPF - MediaElements 不显示多个 H.265 视频

c# - 为什么 Window.Close 事件会传播?