Bug after ActiveChanged Event

Jan 14, 2013 at 2:51 PM

I tried to missuse a ribbon tab as button, so i catch the ActiveChanged event open a popup and set the last active Tab as active again.

But after that, no Buttons on that tab are working anymore until i click the tab with the buttons again.

So how i can get a proper Focus of the tab with everything working?

 

Greetings

moe

Developer
Jan 14, 2013 at 3:03 PM

I'm not sure what is the exact problem that you are facing, but try this:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        ribbon1.Minimized = false;
    }
}

Jan 14, 2013 at 3:38 PM

Doesnt help.

here is a simple click demo with my problem

https://www.dropbox.com/s/iziupv0prag386b/ActiveChangeErrorDemo.zip

 

on tab1 the first button opens a messagebox, if you click the third tab it shows a mesagebox ans switches back to the last active tab.

if u try now to click any button it wont work until u click first on the tab again.

 

the 2 functions:

// the main ribbon tab change listener setting active tab to something not ribbonTab3
private void ribbon1_ActiveTabChanged(object sender, EventArgs e)
        {
            Ribbon rib = (Ribbon)sender;
            if (rib.ActiveTab.Text != "ribbonTab3")
                activeTab = rib.ActiveTab;
        }

// the active change listener on tab3
private void ribbonTab3_ActiveChanged(object sender, EventArgs e)
        {
            RibbonTab active = (RibbonTab)sender;
            if (active.Active)
            {
                MessageBox.Show("Popup without changing something");
                if (activeTab != null)
                    ribbon1.ActiveTab = activeTab;
                else 
                    ribbon1.ActiveTab = ribbonTab1;
            }
        }

Developer
Jan 14, 2013 at 4:19 PM

to my best guess, this is what you are trying to do:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void ribbonButton1_Click(object sender, EventArgs e)
    {
        MessageBox.Show("test");
    }

    private void ribbon1_ActiveTabChanged(object sender, EventArgs e)
    {
        Ribbon rib = (Ribbon)sender;
        if (rib.ActiveTab.Text != "ribbonTab3")
        { }
        else
        {
            rib.ActiveTab = rib.Tabs[0];
            MessageBox.Show("Popup without changing something");
        }
    }

    private void ribbonTab3_ActiveChanged(object sender, EventArgs e)
    {

    }
}

Developer
Jan 14, 2013 at 5:14 PM
Edited Jan 14, 2013 at 5:33 PM

I added the code processing tracking to your original code. From the trace log, I can see that the Ribbon Redraw Process Circle is not been gone through a proper sequence. Causing the Ribbon Redraw the wrong RibbonTab. Below is the tracing log:

ribbonTab3_ActiveChanged
1 - ribbon1.ActiveTab = ribbonTab1

ribbonTab3_ActiveChanged
2 - ribbon1.ActiveTab = ribbonTab1
3 - ribbon1.ActiveTab = ribbonTab1, activeTab = 

ribbon1_ActiveTabChanged
4 - ribbon1.ActiveTab = ribbonTab1
5 - ribbon1.ActiveTab = ribbonTab1, activeTab = Tab: ribbonTab1
6 - ribbon1.ActiveTab = ribbonTab1, activeTab = Tab: ribbonTab1
7 - ribbon1.ActiveTab = ribbonTab1, activeTab = Tab: ribbonTab1

ribbon1_ActiveTabChanged
8 - ribbon1.ActiveTab = ribbonTab3
9 - ribbon1.ActiveTab = ribbonTab3, activeTab = Tab: ribbonTab1

From the above log, my observation is:

The ribbon starts to redraw the element during RibbonTab_ActiveChanged event.

When ribbonTab3 is put focus, ribbonTab3 is consider active and Ribbon starts to redraw the elements. At the mean time, ribbonTab1 is put to passive (dead). After the redraw process completed. Your code switch the focus to ribbonTab1.

Ribbon will show ribbonTab1 but will not redraw it. ribbonTab1 is dead.

You can't change the ribbonTab focus within RibbonTab_ActiveChange event. This will make the Ribbon draw the wrong Tab. Unless the source code is rewrite. But I think that would take some time and most probably not a very impact bug. There are some other more important holes that are needed to be taken care first. I'm not sure is it is going to fixed or not. 

Therefore, for your current situation, if you want to change the ActiveTab, the better place to do it is during Ribbon_ActiveTabChanged event.

By the way, may I know why do you want to do this? If you really want to restrict your user to access certain part of the ribbon, there are more proper way to do it than switching focus.

These are what you can do:

Hide RibbonTab (user can't see)

ribbonTab1.Visible = false;
ribbonPanel.Visible = false;
ribbonButton.Visible = false;

Disable (user can see, but can't do anything)

ribbonPanel.Enable = false;
ribbonButton1.Enable = false;

This is the tracing code that I have written:

public partial class Form1 : Form
{
    int c = 1;
    string process = "";
    Timer timer1 = new Timer();
    RibbonTab activeTab;
    public Form1()
    {
        InitializeComponent();
        timer1.Interval = 100;
        timer1.Tick += new EventHandler(timer1_Tick);
    }

    private void ribbonButton1_Click(object sender, EventArgs e)
    {
        MessageBox.Show("test");
    }

    private void ribbon1_ActiveTabChanged(object sender, EventArgs e)
    {
        process += "\r\nribbon1_ActiveTabChanged\r\n";
        process += c++ + " - ribbon1.ActiveTab = " + ribbon1.ActiveTab.Text + "\r\n";

        Ribbon rib = (Ribbon)sender;
        if (rib.ActiveTab.Text != "ribbonTab3")
        {
            activeTab = rib.ActiveTab;
            process += c++ + " - ribbon1.ActiveTab = " + ribbon1.ActiveTab.Text + ", activeTab = " + activeTab + "\r\n";
        }
        else
        {
            process += c++ + " - ribbon1.ActiveTab = " + ribbon1.ActiveTab.Text + ", activeTab = " + activeTab + "\r\n";
        }
        
        timer1.Stop();
        timer1.Start();
    }

    private void ribbonTab3_ActiveChanged(object sender, EventArgs e)
    {
        process += "\r\nribbonTab3_ActiveChanged\r\n";
        process += c++ + " - ribbon1.ActiveTab = " + ribbon1.ActiveTab.Text + "\r\n";
        
        RibbonTab active = (RibbonTab)sender;
        if (active.Active)
        {
            MessageBox.Show("Popup without changing something");
            if (activeTab != null)
            {
                ribbon1.ActiveTab = activeTab;
                process += c++ + " - ribbon1.ActiveTab = " + ribbon1.ActiveTab.Text + ", activeTab = " + activeTab + "\r\n";
            }
            ribbon1.ActiveTab = ribbonTab1;
            process += c++ + " - ribbon1.ActiveTab = " + ribbon1.ActiveTab.Text + ", activeTab = " + activeTab + "\r\n";
        }
        else
        {

        }
        process += c++ + " - ribbon1.ActiveTab = " + ribbon1.ActiveTab.Text + ", activeTab = " + activeTab + "\r\n";
        timer1.Stop();
        timer1.Start();
    }

    void timer1_Tick(object sender, EventArgs e)
    {
        timer1.Stop();
        MessageBox.Show(process);
        process = "";
        c = 0;
    }

}
Jan 15, 2013 at 9:36 AM

Hi and thanks for the fast reply,

ignoring the ribbontab event like considered worked out for me.Maybe that was a bad idea :P

The reason why i do this nasty hack:

I use my last tab as help Button "?" opening a new form with help and support informations corresponding to the current tab.

So i needed the ribbontab to be clickable but not changing my programs workflow :)

Now all is working fine, great work here!

 

 

greetings moe

Developer
Jan 15, 2013 at 10:38 AM
Edited Jan 15, 2013 at 10:48 AM

I see...

here is another revised version which you may refer:

good luck

public partial class Form1 : Form
{
    ToolTip tip = new ToolTip();
    RibbonTab curTab = null;
    public Form1()
    {
        InitializeComponent();
        if (ribbon1.Tabs.Count > 0)
        {
            curTab = ribbon1.Tabs[0];
        }
    }

    private void ribbonButton1_Click(object sender, EventArgs e)
    {
        MessageBox.Show("test");
    }

    private void ribbon1_ActiveTabChanged(object sender, EventArgs e)
    {
        Ribbon rib = (Ribbon)sender;
        if (rib.ActiveTab.Text != "ribbonTab3")
        {
            curTab = rib.ActiveTab;
        }
        else
        {
            rib.ActiveTab = curTab;
            tip.Show("Popup without changing something", this, this.PointToClient(Cursor.Position), 400);
        }
    }

    private void ribbonTab3_ActiveChanged(object sender, EventArgs e)
    {

    }
}
Jan 15, 2013 at 5:23 PM

that's how i finally sovled it.