Click here to Skip to main content
15,881,139 members
Articles / Desktop Programming / Windows Forms
Article

Adding custom dialogs to your applications

Rate me:
Please Sign up or sign in to vote.
3.46/5 (8 votes)
16 Oct 20052 min read 78.9K   1K   33   9
The article introduces a base dialog form class, which can be used to create all kinds of OK/Cancel type of dialogs. It also gives the basics of custom control creation and form inheritance.

Sample Image - CustomDialogs.png

Introduction

Dialogs are one of the most widely used types of UI windows. One can hardly imagine Windows application without dialogs. Some of them are easy enough like message boxes with several buttons. Their functionality is pretty much covered by the .NET MessageBox class. Some are more complex, like file save/load dialogs or printer settings. These also have their corresponding .NET classes. But what if we need some other form of dialog, not covered by MessageBox or standard dialog controls? In real life applications, the need for custom dialogs arises far too often. Of course, this is a simple matter of putting the necessary controls on the form, adding OK and Cancel buttons, and voila! But why do the same chore over and over again? Let's make the base dialog class and reuse it through inheritance. Isn't it what the OOP is all about?

BaseDialog class

In the beginning, let's ask ourselves what we want of the basic dialog.

First, we need it to have OK and Cancel buttons. Let's put them to the bottom left of the form.

Second, let's draw a line separating them from the rest of the form. Oops, there is no line control in .NET. Never mind, we will make this control ourselves, and learn the basics of custom control creation in the process.

Third, we need to update the layout of these controls in case of resizing of the inheriting form.

C#
protected override void OnLoad(EventArgs e) {
  base.OnLoad (e);
  OnResize(e);
}
 
protected override void OnResize(EventArgs e) {
  base.OnResize (e);
  Line1.Location = new Point(6, this.Size.Height - 64);
  Line1.Size = new Size(this.Size.Width - 18, 2);
  int okx = this.Size.Width - cbOk.Size.Width - 14;
  if(cbCancel.Visible && this.Visible)
    okx -= cbCancel.Size.Width + 4;
  cbOk.Location = new Point(okx, this.Size.Height - cbOk.Size.Height - 32);
  cbCancel.Location = new Point(this.Size.Width - 
           cbCancel.Size.Width - 14, 
           this.Size.Height - cbCancel.Size.Height - 32);
}

And, finally, the most important thing. The inheritors should be able to add some custom actions when the dialog completes, either with DialogResult.Ok or DialogResult.Cancel. These could be some validating actions, with the ability to prevent dialog completion. protected virtual methods with boolean return value will serve this purpose just nice.

C#
private void cbOk_Click(object sender, System.EventArgs e) {
  ExitOk();
}

private void cbCancel_Click(object sender, System.EventArgs e) {
  ExitCancel();
}

protected void ExitOk() { 
  if(cbOk.Enabled==true) {
    if(OnOk()) {
      this.DialogResult = DialogResult.OK;
      this.Close();
    }
  }
}

protected void ExitCancel() {
  if(cbCancel.Enabled==true) {
    if(OnCancel()) {
      this.DialogResult = DialogResult.Cancel;
      this.Close();
    }
  }
}

protected virtual bool OnOk() {
  return true;
}

protected virtual bool OnCancel() {
  return true;
}

Line Control

That one is easy as 1-2-3.

  1. Inherit from System.Windows.Forms.Control.
  2. Paint it ourselves.
    C#
    protected override void OnPaint(PaintEventArgs e) {
      base.OnPaint(e);
      Redraw(e.Graphics);
    }
  3. Repaint it on resize.
    C#
    protected override void OnResize(EventArgs e) {
      base.OnResize(e);
      // height shouldn't change, only length changes
      this.Height = 6;
      Redraw(this.CreateGraphics());
    }

Here goes the painting:

C#
private void Redraw(Graphics g) {
  // drawing dark edge of line
  Pen pen = new Pen(SystemColors.ControlDark, 1);
  Point p1 = new Point(1, 2);
  Point p2 = new Point(this.Width - 2, 2);
  g.DrawLine(pen, p1, p2);
  // drawing bright edge of line
  pen = new Pen(SystemColors.ControlLightLight, 1);
  p1 = new Point(1, 3);
  p2 = new Point(this.Width - 2, 3);
  g.DrawLine(pen, p1, p2);
  p1 = new Point(this.Width - 2, 2);
  g.DrawLine(pen, p1, p2);
}

How to use

Now dialog creation becomes a pleasure. Add an inherited form to your project (choose BaseDialog to inherit from). Add necessary controls and code. Don't forget to make a good use of the Anchor property for added controls. Resize the form to the preferred size. Override OnOk and OnCancel methods to add validation code if necessary.

Add the calling code to the application form. For example:

C#
private void button1_Click(object sender, System.EventArgs e) {
  SampleDialog sd = new SampleDialog();
  if(sd.ShowDialog()==DialogResult.OK) {
    // ...
  }
}

Now some exercises:

  • Try to make a dialog without a Cancel button.
  • Try to make a Yes/No dialog.
  • Try to hide a line and put your controls in a groupbox instead.

All this can be done without making any changes to BaseDialog.

History

  • 16th October 2005 - article submitted.

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


Written By
Web Developer
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralFor the uninitiated Pin
MaxHacker20-Oct-05 9:48
MaxHacker20-Oct-05 9:48 
GeneralRe: For the uninitiated Pin
yfoulon20-Oct-05 22:41
yfoulon20-Oct-05 22:41 
AnswerRe: For the uninitiated Pin
miklovan1-Nov-05 18:15
miklovan1-Nov-05 18:15 
Generalinterest Pin
yfoulon18-Oct-05 8:30
yfoulon18-Oct-05 8:30 
GeneralRe: interest Pin
miklovan18-Oct-05 20:24
miklovan18-Oct-05 20:24 
GeneralNot much need for base dialog class. Pin
wout de zeeuw17-Oct-05 3:33
wout de zeeuw17-Oct-05 3:33 
GeneralRe: Not much need for base dialog class. Pin
miklovan17-Oct-05 4:47
miklovan17-Oct-05 4:47 
QuestionSourcecode? Pin
AxelM16-Oct-05 20:56
AxelM16-Oct-05 20:56 
AnswerRe: Sourcecode? Pin
miklovan16-Oct-05 21:25
miklovan16-Oct-05 21:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.