Search code examples
c#winformstabcontroltabpage

TapePage Image property not being painted


The Set Up: I have a System.Windows.Forms class called ProjectForm. In this form I have a TabControl called tabControl. When the form is initialized, so is the tabControl; however, the tabControl has no TabPages loaded. TabPages are created and loaded at runtime on demand when a user selects an item in a treeView control.

Example Call From ProjectForm:

this.tabControl.TabPages.Add(PageLibrary.CallStackPage(e.Node.Name, e.Node.Text));

(TabPageLibrary) as PageLibrary Class reference

class TabPageLibrary
{
    private TabPageToolBar tabToolBar = new TabPageToolBar();

    public TabPage CallStackPage(string name, string label)
    {
        TabPage tabPage = NewProjectPage();
        tabPage.Name = "STACK:" + name;
        tabPage.Text = label;
        tabPage.Tag = name;
        tabPage.ImageKey = "viewstack.png";
        return tabPage;
    }
    private TabPage NewProjectPage()
    {
        TabPage tabPage = new TabPage();
        tabPage.Padding = new Padding(3);
        tabPage.UseVisualStyleBackColor = true;
        tabPage.Controls.Add(this.tabToolBar);
        return tabPage;
    }
}

Problem When the TabPage is loaded into the control at runtime - no image shows on the tab. the TabControl.ImageList is set to an ImageList that does contain the image I am referencing. Subsequently, the tree control is referencing the same ImageList and the images do show in the tree control.

I would be grateful for any suggestions, solutions or blinding flashes of the obvious you could share.

--Peace

+++ FIX UPDATE ++++

With DonBoitnott's insight - I was able to get these images to properly render with minor refactoring.

New Example Call From ProjectForm:

TabPage page = PageLibrary.NewProjectPage();
this.tabControl.TabPages.Add(page);
page = PageLibrary.CallStackPage(e.Node.Name, e.Node.Text, page);

Refactored (TabPageLibrary) as PageLibrary Class reference

class TabPageLibrary
{
    private TabPageToolBar tabToolBar = new TabPageToolBar();

    internal TabPage CallStackPage(string name, string label, TabPage page)
    {
        page.Name = "STACK:" + name;
        page.Text = label;
        page.Tag = name;
        page.ImageKey = "viewstack.png";
        //TODO: Load Additional CallStack Controls

        return page;
    }

    internal TabPage NewProjectPage()
    {
        TabPage tabPage = new TabPage();
        tabPage.Padding = new Padding(3);
        tabPage.UseVisualStyleBackColor = true;
        tabPage.Controls.Add(this.tabToolBar);
        return tabPage;
    }
}

Thanks again @DonBoitnott, works like a champ!


Solution

  • The code for TabPage tells us that the page will only pick up the image list if it has a parent from which to pull it. Odd, but you can prove it. Here it is:

        //From TabPage.cs
        public string ImageKey
        {
            get
            {
                return this.ImageIndexer.Key;
            }
            set
            {
                this.ImageIndexer.Key = value;
                TabControl parentInternal = this.ParentInternal as TabControl;
                if (parentInternal != null)
                {
                    this.ImageIndexer.ImageList = parentInternal.ImageList;
                }
                this.UpdateParent();
            }
        }
    

    That means you have to ensure you parent the tab page before you attempt to assign the image list key.

    So, with that in mind, here's a bare bones example you can put in any form (you'll need to supply your own art, of course):

    public partial class Form1 : Form
    {
        private ImageList _imgList;
    
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Load(Object sender, EventArgs e)
        {
            foreach (TabPage p in tabControl1.TabPages)
                p.Dispose();
            _imgList = new ImageList();
            _imgList.Images.Add("image0", Properties.Resources.ImageOne);
            _imgList.Images.Add("image1", Properties.Resources.ImageTwo);
            _imgList.Images.Add("image2", Properties.Resources.ImageThree);
            tabControl1.ImageList = _imgList;
        }
    
        private void button1_Click(Object sender, EventArgs e)
        {
    
            Int32 count = tabControl1.TabPages.Count;
            if (count < 3)
            {
                TabPage p = new TabPage();
                p.Name = "page" + count;
                p.Text = "page" + count;
                tabControl1.TabPages.Add(p);
                p.Parent = tabControl1;
                p.ImageKey = "image" + count;
            }
        }
    }