Как часто воссоздается дескриптор UserControl? - PullRequest
8 голосов
/ 23 июля 2011

Я посмотрел событие UserControl.Load для winforms (найдено здесь ) на MSDN и увидел это предупреждение:

Событие Load происходит при создании дескриптора для UserControl. В некоторых случаях это может привести к тому, что событие Load произойдет чаще чем один раз. Например, событие Load происходит, когда UserControl загружается, и снова, если дескриптор воссоздан. (Один из способов, что дескриптор воссоздается путем вызова метода RecreateHandle.) Для учета события Load, происходящего более одного раза, следует поместите любой одноразовый код инициализации в конструктор UserControl вместо обработчика события Load. Кроме того, вы не должны добавлять данные привязки к UserControl в обработчике события Load.

Мой вопрос заключается в том, что, кроме явного вызова RecreateHandle, приведет к воссозданию дескриптора для UserControl? Прежде чем читать это, я всегда помещаю в событие Load все, что должно произойти только один раз. Кроме того (из последнего предложения), где лучше всего добавить привязки данных? Действительно ли имеет значение, если я не собираюсь вызывать RecreateHandle?

1 Ответ

7 голосов
/ 23 июля 2011

Да, это возможно.Это связано с проблемой встроенной функции API Windows CreateWindowEx ().Этот вызов определяет биты стиля для окна.Те же биты стиля также выставляются как свойства элемента управления.Проблема в том, что изменение этого свойства требует повторного вызова CreateWindowEx ().Родное окно Windows для элемента управления уничтожено и воссоздано.У этого есть побочные эффекты, один из них заставляет событие Load снова запускаться.

Демонстрируя это с примером кода:

public partial class UserControl1 : UserControl {
    public UserControl1() {
        InitializeComponent();
    }
    public void TriggerRecreate() {
        if (this.RightToLeft == System.Windows.Forms.RightToLeft.Yes)
             this.RightToLeft = System.Windows.Forms.RightToLeft.No;
        else this.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
    }
    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        Console.WriteLine("onload");
    }
}

Скомпилируйте и отбросьте элемент управления в форме.Добавьте кнопку:

    private void button1_Click(object sender, EventArgs e) {
        userControl11.TriggerRecreate();
    }

и обратите внимание, что окно «Вывод» отображает «onload» каждый раз, когда вы нажимаете кнопку.

Свойство RightToLeft - единственное, что я могу придумать для UserControlэто сделает это.Есть много других форм.Этот класс, однако, имеет специальный код, чтобы его метод OnLoad не запускался более одного разаНе уверен, почему они не сделали этого для UserControl, вероятно, потому что это так редко.Не стесняйтесь игнорировать это.И всегда отдавайте предпочтение конструктору над событием Load, если вы не заботитесь о размере окна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...