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

2

Предположим, у вас есть форма FormBase а все остальные формы наследуются от этой формы.
Например, у меня есть public class Form formTest: FormBase

Что у меня сейчас в ctor от formTest:

public class Form formTest : FormBase
{
    public formTest()
    {
        InitializeComponent();
        Program.MainForm.AddToFormSizes(this, this.Size);
    }
}

Этот код добавляет экземпляр formTest в словарь на главной форме с его size

Это работает, но я хотел бы переместить этот код в FormBase поэтому мне не нужно помещать эту строку кода в каждую унаследованную форму.

public class Form FormBase : Form
{
    public FormBase()
    {
        InitializeComponent();
        Program.MainForm.AddToFormSizes(this, this.Size);
    }
}

Теперь проблема в том, что когда я это сделаю, size будет иметь размер FormBase во время разработки, а не размер formTest.

Есть ли способ в FormBase захватить размер formTest или любой другой формы, унаследованной от FormBase?

для справки, это код AddToFormSizes в MainForm

private Dictionary<Form, Size> _formSizes = new Dictionary<Form, Size>();
public void AddToFormSizes(Form form, Size size)
{
    _formSizes.Add(form, form.Size);
}
  • 0
    Я не думаю, что ты можешь что-то сделать. Размер formTest устанавливается (изменяется) в formTest.InitializeComponent() котором FormBase ничего не знает. Прежде чем это произойдет, formTest.Size - это размер, полученный из FormBase .
  • 1
    Переместить эту вещь (она компилируется?): Program.MainForm.AddToFormSizes(this, this.Size); для protected override void OnHandleCreated(EventArgs e) , после base.OnHandleCreated(e); , Внутри вашей base формы.
Показать ещё 5 комментариев
Теги:
winforms
visual-inheritance

1 ответ

2
Лучший ответ

Проблема:
Используя Form качестве базы для других форм, в конструкторе базового класса ссылка this возвращает Size базового класса вместо Size производного класса.

public class FormBase : Form
{
    public FormBase()
    {
        InitializeComponent();
        Program.MainForm.AddToFormSizes(this, this.Size);
    }
}

Это просто следование последовательности событий:

FormDerived derived = new FormDerived()
=> FormBase.InitializeComponent()
=> FormDerived.InitializeComponent()
derived.Show()
=> FormBase.OnHandleCreated()

Учитывая конструктор формы, производной от FormBase:

public class FormDerived : FormBase
{
     public FormDerived() => InitializeComponents();    
}

когда класс создается впервые:

FormDerived derived = new FormDerived();
derived.Show();

конструктор базового класса (FormBase) вызывается первым.
На этом этапе ссылка this установлена на FormDerived, но все свойства, включая Name и FormDerived формы (Text), установлены на значения базового класса.
Следовательно, вызывая метод, который использует this в конструкторе базового класса:

Program.MainForm.AddToFormSizes(this, this.Size);

this.Size вернет размер базового класса, а не производного класса.

Конструктор FormDerived вызывается следующим. На этом этапе будут установлены все свойства, определенные в методе InitializeComponent().

Если метод AddToFormSizes() перемещен в конструктор производного класса, this будет ссылаться на ожидаемые значения. Но вызов статического метода должен быть вставлен в каждый производный класс FormBase.

AddToFormSizes() можно переместить и OnHandleCreated() из переопределенного OnHandleCreated() базового класса, который будет вызываться при первом показе производной формы:

derived.Show();

вызовет вызов FormBase.OnHandleCreated().

На этом этапе ссылка this уже установлена на производный класс, и все свойства, определенные в InitializeComponent(), уже будут установлены на значения производного класса.
Name, Text и Size включены, конечно.

Здесь this FormDerived со всеми свойствами, установленными в его конструкторе:

public class FormBase : Form
{
    public FormBase() => InitializeComponent();

    protected override void OnHandleCreated(EventArgs e)
    {
         base.OnHandleCreated(e);
         Program.MainForm.AddToFormSizes(this, this.Size);
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню