Use Constructor in Windows Forms to Ensure Proper InitializationArticle #3 on RADby Les Smith |
Use the Constructor in a Windows Form for ensuring that initialization is done properly. Event firing order is not an exact science, and you cannot always depend on the order in which events fire, regardless of what you have seen in the past.
For example, in VB6, you could count on the Form_Load event firing before the Activate event. Therefore, you could set a formLoading variable to True in the Form_Load, test it in the Activate event, and if it was not set, execute some initialization code. I covered a better way to do this in .NET in my previous article on Custom Properties. Having spent a good bit of time in that article, I will now suggest another, probably better way to handle the problem of initialization code in a Windows Form. Unlike VB6, with the Activate Event firing after the Form_Load Event (unless you were debugging and stepping through the Form_Load, in which case the Activate usually did not fire), in VB.NET the sequence of the firing of these two events is not necessarily predictable, and in many, if not all cases, the Activate event will fire prior to the Form_Load.
For this reason Microsoft recommends that you handle initialization code in the Forms Constructor, assuming that you do not have a really time-comsuming initialization that could get time-sliced or do a DoEvents(). If that happens your form could be shown before the initialization is complete. In the code generated by the Windows Form Designer, you always see the following code.
For example, in VB6, you could count on the Form_Load event firing before the Activate event. Therefore, you could set a formLoading variable to True in the Form_Load, test it in the Activate event, and if it was not set, execute some initialization code. I covered a better way to do this in .NET in my previous article on Custom Properties. Having spent a good bit of time in that article, I will now suggest another, probably better way to handle the problem of initialization code in a Windows Form. Unlike VB6, with the Activate Event firing after the Form_Load Event (unless you were debugging and stepping through the Form_Load, in which case the Activate usually did not fire), in VB.NET the sequence of the firing of these two events is not necessarily predictable, and in many, if not all cases, the Activate event will fire prior to the Form_Load.
For this reason Microsoft recommends that you handle initialization code in the Forms Constructor, assuming that you do not have a really time-comsuming initialization that could get time-sliced or do a DoEvents(). If that happens your form could be shown before the initialization is complete. In the code generated by the Windows Form Designer, you always see the following code.
#Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call End Sub |
You can add code after the comment ' Add any initialization.... and it will be executed before the form shows. If this sequence of code is really time consuming, you might consider encapsulating the initialization code in a Private method and calling it from both the Form_Load and Activate events. You would ensure that it was only executed once by placing the following line of code in the constructor.
FormState = State.Loading |
And then, in the Form_Activate event, place the following code. Checking FormState guarantees that you only execute the code once. If you want to see an explanation of the FormState property and its Enums, see the article described earlier on Custom Properties.
Private Sub frmDialogTemplate_Activated(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Activated If FormState = State.Loading Then ' this code will only execute once ' perform initialization code here, ' connect to database, load grids, etc. ' then turn off formLoading so we dont execute again Call InitializeFormMethod() FormState = State.Loaded End If End Sub |
ليست هناك تعليقات:
إرسال تعليق