How to show an ErrorProvider error icon next to a

2019-07-27 11:51发布

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: 1]

I would like the icon to be shown next to the tab page header. Something like this (made with Photoshop):

2]

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 TextBoxes, NumericUpDowns 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.

2条回答
你好瞎i
2楼-- · 2019-07-27 12:00

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

enter image description here

With Icon on Second Tab

enter image description here

查看更多
仙女界的扛把子
3楼-- · 2019-07-27 12:00

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:

enter image description here

Example

To setup the example, follow these steps:

  1. Create a Form.
  2. Drop a TabControl, an ErrorProvider and an ImageList on the Form.
  3. Set ImageList property of tabControl1 to imageList1.
  4. Drop two TextBox on tabPage1.
  5. 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;
    }
    
查看更多
登录 后发表回答