14

我需要在另一个表格之前显示一个表格,这导致我提出以下问题。

为什么一个表单可以有一个起始位置,CenterParent而字段this.Parent等于 null?

它必须知道父节点才能正确定位自己,但它Parent没有设置该字段。这很奇怪。我错过了什么吗?

        Form2 f = new Form2();
        f.ShowDialog();

这就是我在子表单上所做的一切。父级设置为默认窗口位置。无论我将父窗体移动到何处,子窗体都会显示在父窗体的中心。

4

4 回答 4

8

有关所有者的信息通过 API 调用传递给创建的对话框(您可以在 ShowDialog(IWin32Window owner) 方法中的 Reflector 中看到):

UnsafeNativeMethods.SetWindowLong(new HandleRef(this, base.Handle), -8, new HandleRef(owner, handle));

如果在 ShowDialog 调用中没有指定所有者,owner则通过 GetActiveWindow API 调用计算变量:

IntPtr activeWindow = UnsafeNativeMethods.GetActiveWindow();
IntPtr handle = (owner == null) ? activeWindow : Control.GetSafeHandle(owner);

要访问 Owner f 对话框表单,您可以使用GetWindowLong API 调用

IntPtr ownerHandle = NativeMethods.GetWindowLong(nonModalForm.Handle, -8);
于 2012-06-08T08:19:23.187 回答
3

在 Winforms 中,窗口的父级和所有者之间的区别有点混乱。在这种情况下,CenterParent 真正的意思是 CenterOwner。不是 Windows 功能,它是在 Winforms 中实现的,由基本的 Form.OnLoad() 方法完成。一个对话框应该总是有一个所有者,当你没有在 ShowDialog() 调用中指定一个时,它会寻找一个所有者。其中使用 GetActiveWindow() 作为最佳猜测。

要亲自查看,请在对话框表单中重载 OnLoad,如下所示:

public partial class Form2 : Form {
    public Form2() {
        InitializeComponent();
        this.StartPosition = FormStartPosition.CenterParent;
    }
    protected override void OnLoad(EventArgs e) {
        //base.OnLoad(e);
    }
}

请注意,它不再以所有者为中心。

可以在Reference Source,Form.cs类,OnLoad方法中看到相关代码:

if (GetState(STATE_MODAL)) {
    FormStartPosition startPos = (FormStartPosition)formState[FormStateStartPos];
    if (startPos == FormStartPosition.CenterParent) {
        CenterToParent();
    }
    else if (startPos == FormStartPosition.CenterScreen) {
        CenterToScreen();
    }
}
于 2012-06-08T09:42:00.560 回答
1

我相信出于某种原因,此信息由 .NET Framework 内部存储。无论如何,如果您想访问父表单,可以将其设置为子表单的Owner 属性

Form form = new Form();
form.Owner = this;
form.Show();

然后在子窗体中,您可以使用 Owner 属性访问父窗体。当一个表单被另一个表单拥有时,它会被最小化并与所有者表单一起关闭。拥有的表格也永远不会显示在其拥有者表格的后面,如果我理解正确的话,这正是您所需要的。

于 2012-06-08T08:46:11.080 回答
0

此代码将打开父 TAG 中间的对话框。

    ObjectDistrubution od = new ObjectDistrubution();
    od.StartPosition = FormStartPosition.CenterParent;
    od.ShowDialog();
于 2013-05-07T09:18:34.913 回答