Question

I have a WPF application using Avalon Dock 2.0 as docking manager. I'm facing a problem concerning the standard positioning of new opened tabs Avalon Dock is performing.

As long as all tabs fit into the tab bar a new tab is appended on the rightmost position of the tab bar. As soon as the new tab does not fit into the bar the new tab is added at the leftmost position making the former rightmost tab dissappear.

I know this is Visual Studio standard behaviour but in my application the order has a meaning. This means a new tab should either always be added on the leftmost OR the rightmost position. The switch is very confusing for the user.

Is there a way to make Avalon Dock add a new tab always on either the leftmost or the rightmost position?

Was it helpful?

Solution

I figured it out. I changed the code in the ArrangeOverride(Size finalSize) method from DocumentPaneTabPanel to prevent the repositioning of the current tab to the first position.

It now hides tabs on the left of the current one not fitting the panel - hiding the most left ones first. The tabs on the right of the current one are hidden as well - here the most right ones are hidden first. If there is an overflow the current tab is always the rightmost on the panel. This is a bit dirty at the moment but I think implementing this in a nicer way should not be that hard.

Here is the code:

    protected override Size ArrangeOverride(Size finalSize)
    {
        double offset = 0.0;
        var children = Children.Cast<UIElement>().Where(ch => ch.Visibility != System.Windows.Visibility.Collapsed).ToList();
        if (children.Count > 0)
        {
            //find currently selected tab
            int i = 0;
            for (i = 0; i < children.Count(); i++)
            {
                TabItem doc = (TabItem)children[i];
                var layoutContent = doc.Content as LayoutContent;
                if (layoutContent.IsSelected)
                    break;
            }

            //calculate how many tabs left from the currently selected would fit in the panel
            int cur_ind = i;
            TabItem current_item = (TabItem)children[cur_ind];
            List<TabItem> t_to_display = new List<TabItem>();
            while (cur_ind >= 0 && offset + current_item.DesiredSize.Width <= finalSize.Width)
            {
                current_item = (TabItem)children[cur_ind];
                current_item.Visibility = System.Windows.Visibility.Visible;
                offset += current_item.DesiredSize.Width + current_item.Margin.Left + current_item.Margin.Right;
                t_to_display.Add(current_item);
                --cur_ind;
            }

            //arrange the fitting tabs on the left
            double cur_offset = offset;
            foreach (TabItem t in t_to_display)
            {
                cur_offset -= t.DesiredSize.Width + t.Margin.Left + t.Margin.Right;
                t.Arrange(new Rect(cur_offset, 0.0, t.DesiredSize.Width, finalSize.Height));
            }

            //arrange the tabs on the right
            cur_ind = i + 1;
            while (cur_ind < children.Count && offset + current_item.DesiredSize.Width <= finalSize.Width)
            {
                current_item = (TabItem)children[cur_ind];
                current_item.Visibility = System.Windows.Visibility.Visible;
                current_item.Arrange(new Rect(offset, 0.0, current_item.DesiredSize.Width, finalSize.Height));
                offset += current_item.DesiredSize.Width + current_item.Margin.Left + current_item.Margin.Right;
                cur_ind++;
            }

            while(cur_ind < children.Count)
            {
                current_item = (TabItem)children[cur_ind];
                current_item.Visibility = System.Windows.Visibility.Hidden;
                cur_ind++;
            }
        }

        return finalSize;

    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top