Edit:
This is not a duplicate of Icons in TabControl C# - How?. The question there is about adding icons to tab pages. Here it is about how the change the error provider error icon position to be inside the header instead of to the right of the tab page itself. Also, the error provider error icon has the functionality that when you hover the mouse on it, you see the error text, which you do not see if you simply add an icon to the header.
I have a form with a TabControl
. The form has also an ErrorProvider
. When I try to use the following code:
errorProvider1.SetError(tabPage1, "error");
The error icon is shown to the right of the tab page, and it is cut-off by the tab control itself:
I would like the icon to be shown next to the tab page header. Something like this (made with Photoshop):
I do not know where to start, or how to approach this.
Edit:
I have a class responsible for adding errors to a control, and showing them using an error provider. This class is used for TextBox
es, NumericUpDown
s etc. I would like to use it also for TabPages
. The problem is that when I use it for tab pages I get the result shown above. The trick of adding an error icon to the header using an ImageList
and then add a tooltip is not good, because it is specific to tab pages, and I cannot implement it in my class which is general to all controls. So I really need to change the settings of the tab page so when I use errorProvider.SetError(...)
it is shown in the header.
You can do the following.
Rectangle rc = tabControl1.GetTabRect(0); // Replace with the index of Tab required
errorProvider1.SetIconPadding(tabControl1, -rc.Left-20);;
errorProvider1.SetError(tabControl1, "Error String");
You also need to set
errorProvider1.SetIconAlignment(tabControl1, ErrorIconAlignment.TopLeft);
Sample (With Second Tab Selected - based on comments),
You would need to prepend whitespace to your TabPage Text to ensure there is sufficient space for showing the icon
With Icon on Second Tab
ErrorProvider
shows error icon of the TabPage
in tab page's client area.
By playing with IconAlignment
or IconPadding
, you can show error icon of TabControl
on one of the tab pages' headers, but it's error icon for the whole TabControl
.
In a real application each of the tab pages can contain controls which are not valid and you may want to show the validation icon on tab pages not for the tab control.
My suggestion is using tab page icon by setting ImageList
containing the error icon as image list of the TabControl
and by setting ImageIndex
of the TabPage
, show or hide the image icon. This way you can show the error icon for every tab page which needs it:
Example
To setup the example, follow these steps:
- Create a
Form
.
- Drop a
TabControl
, an ErrorProvider
and an ImageList
on the Form
.
- Set
ImageList
property of tabControl1
to imageList1
.
- Drop two
TextBox
on tabPage1
.
I assume, just for example, you are going to validate these two text box controls using Validating
event. The key point is here. When you validate any control, check if it's hosted in a TabPage
, check validity of all children of TabPage
and set the error icon based on that:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.AutoValidate = AutoValidate.EnableAllowFocusChange;
imageList1.ColorDepth = ColorDepth.Depth32Bit;
imageList1.Images.Add(errorProvider1.Icon);
tabControl1.ImageList = imageList1;
textBox1.Validating += textBox_Validating;
textBox2.Validating += textBox_Validating;
}
private void textBox_Validating(object sender, CancelEventArgs e)
{
var textBox = (TextBox)sender;
if (string.IsNullOrEmpty(textBox.Text))
{
this.errorProvider1.SetError(textBox, "Value is required.");
e.Cancel = true;
}
else
this.errorProvider1.SetError(textBox, null);
var tabPage = textBox.Parent as TabPage;
if (tabPage != null)
ValidateTabPage(tabPage);
}
void ValidateTabPage(TabPage tabPage)
{
var tabIsValid = tabPage.Controls.Cast<Control>()
.All(x => string.IsNullOrEmpty(errorProvider1.GetError(x)));
if (tabIsValid)
tabPage.ImageIndex = -1;
else
tabPage.ImageIndex = 0;
}