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

Form.Parent и StartPosition.CenterParent

Мне нужно показать форму точно перед другой формой, это привело меня к следующему вопросу.

Как получилось, что форма может иметь начальную позицию как CenterParent, когда поле this.Parent равно null?

Он должен знать родителя, чтобы правильно позиционировать его, но это поле Parent не задано. Это странно. Я что-то пропустил?

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

Это все, что я делаю на дочерней форме. Родитель установлен в положение по умолчанию для окон. Независимо от того, где я перемещаю родительскую форму, ребенок отображается в центре родителя.

4b9b3361

Ответ 1

Информация о владельце передается в созданный диалог через вызов API (вы можете видеть, что в Reflector в методе ShowDialog (IWin32Window owner)):

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

Если в вызове ShowDialog нет владельца, переменная owner вычисляется с помощью вызова API GetActiveWindow:

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

Чтобы получить доступ к форме диалога Owner f, вы можете использовать вызов GetWindowLong API:

IntPtr ownerHandle = NativeMethods.GetWindowLong(nonModalForm.Handle, -8);

Ответ 2

Разница между родителем и владельцем окна немного запутана в 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();
    }
}

Ответ 3

Я полагаю, что эта информация хранится внутри .NET Framework по какой-то причине. В любом случае, если вы хотите получить доступ к родительской форме, вы можете установить ее свойство владельца дочерней формы:

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

Затем в дочерней форме вы можете получить доступ к родительской форме, используя свойство Owner. Когда форма принадлежит другой форме, она сворачивается и закрывается формой владельца. Собственные формы также не отображаются за их формой владельца, что является безусловным, что вам нужно, если я правильно понял вас.

Ответ 4

Этот код откроет диалог в середине родительского TAG.

    ObjectDistrubution od = new ObjectDistrubution();
    od.StartPosition = FormStartPosition.CenterParent;
    od.ShowDialog();