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 DataSet
s. If you are not, please give yourself a little slap on the wrist, and then go read some articles about Strongly-Typed DataSet
s. If you're not using Strongly-Typed DataSet
s, 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:
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 TextBox
es and ComboBox
es:
private void CheckNewRecordRequiredControls(Control ctl)
{
foreach (Control control in ctl.Controls)
{
if (control.Controls.Count > 0)
{CheckNewRecordRequiredControls(control) ; }
if ((control is TextBox && control.Text == "") ||
(control is ComboBox &&
(control as ComboBox).SelectedIndex == -1))
{
if (control.DataBindings.Count == 0) { continue ; }
string boundField =
control.DataBindings[0].BindingMemberInfo.BindingField;
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
{
continue ;
}
if (GetDataSet().Tables.Columns.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],"") ;
I hope you find this article useful.