3 Replies - 5307 Views - Last Post: 16 March 2012 - 08:24 AM Rate Topic: -----

#1 cokacola  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 5
  • View blog
  • Posts: 64
  • Joined: 23-July 10

Cross-thread tab drawing

Posted 13 March 2012 - 01:54 AM

Basically, I have a TabControl.
I am drawing the text for the headers myself so they can be coloured when required.
The calls to change colour are on a different thread then the one the TabControl is, so I am using delegates and such for cross-thread operations.
Unfortunatly my method is not exactly reliable.

Here is the cross-threading part:
delegate TabControl getTabDelegate();
        private TabControl getTab()
        {
            if (this.channelTabs.InvokeRequired)
            {
                getTabDelegate d = new getTabDelegate(getTab);
                this.Invoke(d);
                return null;
            }
            else
            {
                return channelTabs;
            }
        }

and here is the drawing code:
private void channelTabs_DrawItem(object sender, DrawItemEventArgs e)
        {
            try
            {
                TabControl ct = getTab();
                using (Brush br = new SolidBrush(TabColors[ct.TabPages[e.Index]]))
                {
                    e.Graphics.FillRectangle(br, e.Bounds);
                    SizeF sz = e.Graphics.MeasureString(ct.TabPages[e.Index].Text, e.Font);
                    e.Graphics.DrawString(ct.TabPages[e.Index].Text, e.Font, Brushes.Black, e.Bounds.Left + (e.Bounds.Width - sz.Width) / 2, e.Bounds.Top + (e.Bounds.Height - sz.Height) / 2 + 1);

                    Rectangle rect = e.Bounds;
                    rect.Offset(0, 1);
                    rect.Inflate(0, -1);
                    e.Graphics.DrawRectangle(Pens.DarkGray, rect);
                    e.DrawFocusRectangle();
                }
            }
            catch(Exception err)
            {
                MessageBox.Show(err.Message, "1");
            }
        }

As you can see, in some cases getTab(); returns null, which isn't exactly helpful.
Is there any more...reliable method of doing this?

Here is the method that is called from the second thread to change the header colour:
private void SetTabHeader(TabPage page, Color color)
        {
            TabColors[page] = color;
            channelTabs.Invalidate();
        }

Without the cross-threading part, of course, I get exceptions thrown.

And as you can probably imagine, channelTabs is the GUI tab control.

Any help is apperciated, thanks!

EDIT:
Oh yea, and if it is actually helpful:
private Dictionary<TabPage, Color> TabColors = new Dictionary<TabPage, Color>();

This post has been edited by cokacola: 13 March 2012 - 01:55 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Cross-thread tab drawing

#2 eclipsed4utoo  Icon User is offline

  • Not Your Ordinary Programmer
  • member icon

Reputation: 1524
  • View blog
  • Posts: 5,960
  • Joined: 21-March 08

Re: Cross-thread tab drawing

Posted 14 March 2012 - 02:01 PM

Quote

As you can see, in some cases getTab(); returns null, which isn't exactly helpful.


Well of course it does. You tell it to return null when InvokeRequired is true.

Why are you doing the logic to determine the color on a background thread? Is it that time consuming for that logic to run?
Was This Post Helpful? 0
  • +
  • -

#3 cokacola  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 5
  • View blog
  • Posts: 64
  • Joined: 23-July 10

Re: Cross-thread tab drawing

Posted 16 March 2012 - 03:33 AM

I'm doing it in a background thread because the client code runs in a background thread, so the events for it run in a background thread and the events for it are where the code that calls the tab colour change are, not really sure how else to do it, if the client code were in the same thread as the GUI then the GUI would be frozen a lot I guess.
I actually solved this with some sligtly less...silly...code.
Was This Post Helpful? 0
  • +
  • -

#4 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4469
  • View blog
  • Posts: 7,780
  • Joined: 08-June 10

Re: Cross-thread tab drawing

Posted 16 March 2012 - 08:24 AM

Next time, consider using a BackgroundWorker. It's still threading, but it's a lot more user-friendly, and a lot easier to update the GUI from without having to invoke.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1