5,667,575 members and growing! (9,917 online)
Email Password   helpLost your password?
Languages » C# » Windows Forms     Intermediate

Centralize Show Form Validation Logic

By Jason Apergis

This article will show how to centralize your logic when opening a Windows Form.
C#, Windows, .NET 1.0, .NET 1.1, .NET, WinForms, Visual Studio, VS.NET2002, VS.NET2003, Dev

Posted: 17 May 2005
Updated: 17 May 2005
Views: 19,213
Bookmarked: 8 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
3 votes for this Article.
Popularity: 1.34 Rating: 2.80 out of 5
0 votes, 0.0%
1
1 vote, 33.3%
2
1 vote, 33.3%
3
1 vote, 33.3%
4
0 votes, 0.0%
5

Introduction

This article is intended to show you an easy way to centralize your logic when opening a Windows Form.

Background

It is common that when developing a Windows application you will want to perform either some type of operation or validation that will determine whether a form can be opened. Many times the same code will need to be executed in different places throughout your project. Obviously a good design will not litter the application with the same code over and over again. So, why not use the constructor of a form to perform any operation or validation logic prior to opening the form? Using the constructor of a form to do certain operations does have limitations. For instance, if you have FormA and you perform all security validation(s) in the constructor, nothing will stop the developer from doing the following and making the form visible to the user:

FormA frm = new FormA();
FormA.Show();

In this example, putting security logic in the FormA constructor is too early and we want to defer that logic to a later point in time. Putting the logic in the Show() method would be the latest point prior to the form opening. Doing this also forces your code to be more defensive.

Another question someone may ask is why not put the security logic in the Activated, Enter or Load events of the form? In some situations that would be fine, but the raising of these events actually infers the form may have been made visible to the user. Your code will not be very clean if you are to put the same logic into every event handler previously mentioned. If the form cannot be made visible to the user, for whatever reason, it is simpler to stop the process before the events are raised.

Assumptions

I am making a couple assumptions when proposing this solution:

  1. The code base you are working with has a base form where all of the forms in your project inherit from.
  2. The constructor is being used for initializing the presentation of the form.
  3. The constructor is not being used to perform any logic that will be used to determine whether the form will be opened.
  4. The constructor is not performing any logic that will be committed to any objects that are passed into the form's constructor. This is important because if the constructor is committing a new state to an object passed into the form's constructor, and the form will not be opened when the Show() or ShowDialog() methods are called, you will be in a not so happy place.

Solution

To solve this problem, we will simply use the keyword new to override the base implementation of Show() and ShowDialog() in the base form (BaseForm) of our project. A derived Windows Form cannot override the Show() and ShowDialog() methods, so we will override the methods using the keyword new, insert our own logic and then call to the base method.

public new virtual DialogResult ShowDialog() {
     if (CanOpenForm)
          return base.ShowDialog();

     ShowFormError();
     return DialogResult.None;
}

public new virtual DialogResult ShowDialog(IWin32Window owner) {
     if (CanOpenForm)
          return base.ShowDialog(owner);

     ShowFormError();
     return DialogResult.None;
}

public new virtual void Show() {
     if (CanOpenForm) {
          base.ShowDialog();
     } else {
          ShowFormError();
          return;
     }
}

protected virtual bool CanOpenForm {
     get {
          ///preform general validation logic for opening all forms here.

          return true;
     }
}

protected virtual void ShowFormError() {
     ShowFormError("Form could not be opened.");
}

protected virtual void ShowFormError(string sErrorMessage) {
     ShowFormError(sErrorMessage, "Form Open Error", 
                 MessageBoxButtons.OK, MessageBoxIcon.Error);
}

protected virtual void ShowFormError(string sErrorMessage, string sCaption, 
     MessageBoxButtons buttons, MessageBoxIcon icon) {

     MessageBox.Show(sErrorMessage, sCaption, buttons, icon);
}

Let's now review the above code. The Show() and ShowDialog() methods all check the CanOpenForm property before the base method is called. You have the option of making a different CanOpenForm property for each Show() or ShowDialog() method but more than likely using the same property will be good enough. Note that the CanOpenForm property has been made virtual, this is so all derived forms can override this property and add form specific validation. Also note that I have made Show() and ShowDialog() virtual so you can completely override the validation logic on a derived form.

Note that in the overrides of ShowDialog(), specifically return DialogResult.None if CanOpenForm failed. This is because base.ShowDialog() by default will return DialogResult.None. If the user were to press the "X" in the top right hand corner of a modal dialog form, DialogResult.Cancel would be returned. We do not want to return that value because it would infer that the dialog form might have been made visible to the user when in actuality it had not.

Another neat thing you can do is to ensure that a form is being opened properly. For instance, let's say your project has a BaseForm and BaseDialogForm that inherits from the BaseFrom. The BaseDialogForm is meant to be a modal form that all other modal forms (with OK and Cancel buttons) will inherit from. Since this from is a modal form, you may want to override the Show() method.

public override void Show() {
     System.Diagnostics.Debug.Assert(false, 
               "All Dialog Box Forms should be modal.");
     base.Show();
}

When overriding the base Show() method, I simply send a debug assert to the developer saying that this method should not be used. Although the method still calls the base.Show(), it is not overly obtrusive in its implementation. You have many other options:

  1. Force the issue by calling System.Diagnostics.Debug.Fail or do not call any method at all.
  2. Force the overridden Show() method to call ShowDialog().
  3. Anything else, there is no hard and fast rule, it is what ever makes sense.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Jason Apergis


I received an undergrad degree from Virginia Tech in Management Science and IT and completed a masters program in Information Technology at night as well through Virginia Tech.

I have been doing federal contracting in the Washington DC area since graduating, working for BearingPoint most of the time. I have two years of classic ASP experience, and three years of C# experience. Such things as understandings of design patterns, refactoring and code re-useability are very important to me as a professional.

I am an avid Virginia Tech football fan, play ice hocky a couple times a week, I try not to annoy my wife and I love to wrestle with my english bulldog Winston.
Occupation: Web Developer
Location: United States United States

Other popular C# articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
  (Refresh) 
-- There are no messages in this forum --

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 17 May 2005
Editor: Smitha Vijayan
Copyright 2005 by Jason Apergis
Everything else Copyright © CodeProject, 1999-2008
Web16 | Advertise on the Code Project