Click here to Skip to main content
Click here to Skip to main content

ErrorProvider as a 'Warning Provider'

, 21 Jun 2005 CPOL
Rate this:
Please Sign up or sign in to vote.
Use the ErrorProvider to display friendly 'Value Required' warnings.

Sample screenshot

Introduction

I like providing a friendly user interface for users of the applications I work on. One way to do that is to 'point out' required fields, when they're adding new records.

Background

I have always liked using the ErrorProvider as an easy way to alert the user that something is wrong. Since the icon and message associated with the ErrorProvider can easily be changed, I figured that would be a good way to create a 'Warning Provider'.

Prerequisites

First of all, I need to point out that we will be accessing the DataBinding information on our controls. So, you need to be using bound controls for this to work.

Secondly, we will be checking constraints on our DataSet. Hopefully anyone reading this article is making full use of Strongly-Typed DataSets. If you are not, please give yourself a little slap on the wrist, and then go read some articles about Strongly-Typed DataSets. If you're not using Strongly-Typed DataSets, the 'Warning Provider' will still work, as long as you have set the appropriate constraints.

Thirdly, if you don't want the default error icon for your 'warning', then add an ImageList control to your control/form, and add the 16x16 icon that you wish to use.

Fourthly, create a method called 'GetDataSet()' which will give you your DataSet object.

Setting up the 'Warning Provider'

For the sake of this article, let's assume you have a strongly typed DataSet called AppDataSet, and that it contains a DataTable called Customer, with two required fields: Customer_Name and Customer_Type.

In your form/control, in the declarations section, add the following lines of code:

private ErrorProvider  warningProvider = new ErrorProvider();
warningProvider.ContainerControl = this ;

Now, some of you may have experienced a similar problem when changing the icon for an error provider. If I had placed the ErrorProvider on my control/form at design time and then changed the icon, I would always get a SystemException when I started my app. After unsuccessfully attempting to troubleshoot that, I decided to change the icon through code, and I've never had any problems with that.

To change the icon on your error provider, use the following code:

//assuming the image I want is at position 0
this.warningProvider.Icon = 
  Icon.FromHandle(((Bitmap)YourImageList.Images[0]).GetHicon());

I also change the blink style to NeverBlink for this, since I don't want to scare the user.

this.warningProvider.BlinkStyle = ErrorBlinkStyle.NeverBlink;

CheckNewRecordRequiredControls Method

This is the meat of this article. This is a recursive method that will check all controls and contained controls. It will check each control for databindings, and will figure out if that control is bound to a required field.

For the purpose of this article, we will only check TextBoxes and ComboBoxes:

/// <summary>
/// Recursively check all controls contained
/// within [ctl] to see if they required a value
/// </summary>
/// <param name="ctl">parent control that contains databound controls</param>
private void CheckNewRecordRequiredControls(Control ctl)
{
    foreach (Control control in ctl.Controls)
    {
        //if the current control contains additional controls, run recursively
        if (control.Controls.Count > 0)
            {CheckNewRecordRequiredControls(control) ; }
        if ((control is TextBox && control.Text == "") ||
            (control is ComboBox && 
            (control as ComboBox).SelectedIndex == -1))
        {
        //make sure we have databindings
        if (control.DataBindings.Count == 0) { continue ; }
        //get bound field name
        string boundField = 
          control.DataBindings[0].BindingMemberInfo.BindingField;
        //get the bound table -- if we're bound to a dataview, 
        //we need to get the table from that
        // otherwise just get to the DataTable
        string boundTable = string.Empty ;
        if (control.DataBindings[0].DataSource is DataView)
        {
            boundTable = (control.DataBindings[0].DataSource 
                              as DataView).Table.TableName ;
        }
        else if (control.DataBindings[0].DataSource is DataTable)
        {
            boundTable = (control.DataBindings[0].DataSource 
                                   as DataTable).TableName ;
        }
        else
        {
            //not set up to handle bindings to anything 
            //other than DataView or DataTable
            continue ;
        }
        if (GetDataSet().Tables[boundTable].Columns[boundField].AllowDBNull == false)
        {
            warningProvider.SetError(control,"Required Field") ;
        }
    }
}

Clearing WarningProvider

Once the WarningProvider has been set, you do need to manage clearing it when it's appropriate. I have event handlers for the 'Leave' event of my controls. I check to see if the control is valid and then I clear the WarningProvider. If all you want to do is make sure a value has been entered, then you could use a procedure similar to 'CheckNewRecordRequiredControls', and if the control has a value then clear the WarningProvider like this:

warningProvider.SetError([control],"") ; //the "" will clear the warning icon

I hope you find this article useful.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Paul Brower
Choice Genetics US
United States United States
Seasoned IT Professional. Currently the IT Director for Choice Genetics, and also the world-wide manager for IT Projects related to R&D for Groupe Grimaud (our parent company).
 
I've spent about half my career as a contractor. I've lived all over the place, but currently reside near St. Louis, Missouri. Moved out here from Roseville, California in Feb-2005. No regrets yet.
 
Over the recent years I've written software for:
- Disposing of radioactive and toxic waste.
- Disposing of surplus inventory during the Decommission of McClellan Air Force Base.
- Facilitating genetic improvement for Swine Breeding.
- Managing children placed in State custody.
- Dealing with commercial trucking delivery schedules.
- Tracking high resolution images from archeological digs.
- Project Management for the roofing industry.
- Processing engines for credit card transactions.
Follow on   LinkedIn

Comments and Discussions

 
GeneralDataBindings may be DataSet . See corrected version Pinmembercrazy_elephant12-Jan-06 22:22 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.141015.1 | Last Updated 21 Jun 2005
Article Copyright 2005 by Paul Brower
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid