Dialogs






Dialogs

You've seen how to create and show forms, but you can instead show them as dialogs. Although it's not always the case, dialogs are typically modal and exist to take information from a user before a task can be completedin other words, a dialog is a form that has a "dialog" with the user. For example, we created the Options dialog in Figure by right-clicking on a project in Solution Explorer and choosing Add Windows Form. Implementing the form was a matter of exposing the favorite color setting as a property, dropping the controls onto the form's design surface, and setting the ControlBox property to false so that it looks like a dialog.

20. A Dialog


You can use this form as a modal dialog by calling the ShowDialog method:

// OptionsDialog.cs
partial class OptionsDialog : Form {
  public OptionsDialog() {
    InitializeComponent();
  }

  void optionsToolStripMenuItem_Click(object sender, EventArgs e) {
    OptionsDialog dlg = new OptionsDialog();
    dlg.FavoriteColor = this.BackColor;
    if( dlg.ShowDialog() == DialogResult.OK ) {
      this.BackColor = dlg.FavoriteColor;
    }
  }
}

Notice that the custom OptionsDialog class is instantiated, but before it's shown, the initial color value is passed in via the FavoriteColor property. When the modal ShowDialog method completes, it returns the value of the DialogResult enumerationin this case, either OK or Cancel. Although it's possible to implement the Click events for the OK and Cancel buttons inside the OptionsDialog class, there's a much easier way to make OK and Cancel act as they should: You set each button's DialogResult property appropriately, and set the OptionsDialog form's AcceptButton and CancelButton properties to the OK button and the Cancel button, respectively. In addition to closing the dialog and returning the result to the caller of ShowDialog, setting these properties enables the Enter and Esc keys and highlights the OK button as the default button on the form.

You may still feel the need to handle the OK Click event to validate data captured by the dialog. Although you can do that, Windows Forms provides built-in support for validation. In conjunction with an ErrorProvider component, you can handle the control's Validating event and thereby validate the contents of each control when the user moves focus from the control. For example, if we want the user to specify a color with some green in it, we can drop an ErrorProvider component onto the OptionsDialog form and handle the Validating event for the Change button whenever it loses focus:

// OptionsDialog.cs
partial class OptionsDialog : Form {
  ...
  void changeColorButton_Validating(object sender, CancelEventArgs e) {
    byte greenness = this.changeColorButton.BackColor.G;
    string err = "";
    if( greenness < Color.LightGreen.G ) {
      err = "I'm sorry, we were going for leafy, leafy...";
      e.Cancel = true;
    }
    this.errorProvider.SetError(changeColorButton, err);
  }
}

In the Validating event handler, notice that we set the CancelEventArgs.Cancel property to true; this cancels the loss of focus from the control that caused the validating event. Also notice the ErrorProvider.SetError invocation; SetError accepts as arguments the control that is being validated and a string, which is the message displayed by the ErrorProvider. When this string is null, the error provider's error indicator for that control is hidden. When this string contains something, the error provider shows an icon to the right of the control and provides a tooltip with the error string, as shown in Figure.

21. ErrorProvider Providing an Error (See Plate 1)


The Validating event handler is called whenever focus is moved from a control whose CausesValidation property is set to true (the default) to another control whose CausesValidation property is also set to true.

One side effect of setting CancelEventArgs.Cancel to true is that focus is retained on an invalid control until valid data is entered, thereby preventing users from navigating away from the control. The Form class's AutoValidate property dictates this behavior to remain consistent with previous versions of Windows Forms. AutoValidate's default value is EnablePreventFocusChange. If you prefer to let your users navigate away from invalid controlsgenerally considered better from a user's point of viewyou can change AutoValidate to EnableAllowFocusChange in the Properties window, as shown in Figure.

22. Setting the AutoValidate Property to Allow Focus to Change from an Invalid Control


The host form's AutoValidate value applies to all controls hosted by the form that perform validation. AutoValidate and validation are explored further in Chapter 3: Dialogs.

If you do allow free navigation across invalid controls, it means that users can conceivably tab to, or click, a form's AcceptButton without having any valid data on the form. Consequently, you need to write additional code to validate the entire form from the AcceptButton. Fortunately, the Form class exposes the Validate method for this purpose:

// OptionsDialog.cs
partial class OptionsDialog : Form {
  ...
  void okButton_Click(object sender, EventArgs e) {
    // Validate form
    bool isValid = this.Validate();
    // Don't close form if data is invalid
    if( !isValid ) this.DialogResult = DialogResult.None;
  }
}

The Validate method fires the Validating event for each of the controls hosted on a form, harvesting the results along the way. If any of the Validating event handlers set CancelEventArgs.Cancel to true, Validate returns false.

ErrorProvider and the Validating event give you most of what you need for basic validation, but more complicated validation scenarios require some custom coding. Chapter 3 explores these. It also discusses the standard Windows Forms dialogs and explains how to support communication between your modal and modeless dialogs and other parts of your application.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows