Tabs Studio Blog (organizing Visual Studio document tabs)

March 4, 2011

Highlight tabs with Marker

Filed under: Uncategorized — Tags: , — Sergey Vlasov @ 2:42 pm

David Peris suggested an interesting idea for Tabs Studio: “For people like me working in huge solutions, with a bunch of projects and files, sometimes we need to highlight a few tabs, temporarily, to quickly come back to them. Color rules would make the trick if the tabs share some criteria, but they can be slow to setup just for temporary highlighting. It would be great to be able to quick color some tabs, like for example Ctrl+click a tab would highlight it, and Ctrl+click again would de-highlight it. Maybe an option in the right click menu as “Remove highlights” or something like that would be the perfect complement to this option.”

I’ve created the new Marker add-in for this functionality. Ctrl+Click a tab highlights it and Ctrl+Click again removes highlighting. No additional context menu options yet, but it can be added later:

Several tabs highlighted with the default style

Several tabs highlighted with the default style

The default highlighting style provided by Marker decorates TabInternals with the red gradient background. You can choose to decorate another tab element or just change the highlighting color in a custom Tabs Studio style:

<Style TargetType="TabsStudio:TabInternals" BasedOn="{StaticResource DefaultTabInternalsStyle}">
    <Style.Triggers>
      <DataTrigger Binding="{Binding Path=(TabsStudioMarker:Properties.IsHighlighted), 
                 RelativeSource={RelativeSource AncestorType=TabsStudio:Tab}}" Value="True">
          <Setter Property="Background">
              <Setter.Value>
                   <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                       <GradientStop Color="Transparent" Offset="0.8"/>
                       <GradientStop Color="Green" Offset="1"/>
                   </LinearGradientBrush>
              </Setter.Value>
          </Setter>
      </DataTrigger>
  </Style.Triggers>
</Style>
Tabs highlighted with the custom green color

Tabs highlighted with the custom green color

Download link: Marker v1.0.0.

February 26, 2011

Horizontal tab alignment

Filed under: Uncategorized — Tags: , — Sergey Vlasov @ 9:07 pm

In Visual Studio 2010 horizontal tab alignment is a little off, note the close tab button is near the tab name instead of being docked to the right:

Left tab alignment in Visual Studio 2010

Left tab alignment in Visual Studio 2010


In Visual Studio 2008 and even in the Visual Studio 2010 floating tool window tab alignment is correct:
Stretch tab alignment in the floating Visual Studio 2010 tool window

Stretch tab alignment in the floating Visual Studio 2010 tool window


Turns out horizontal tab alignment is Stretch by default in TabItem‘s control template, but also inherited from the HorizontalContentAlignment property of a ItemsControl visual ancestor. Tabs Studio doesn’t use ItemsControl (this is why in Visual Studio 2008 and in the separate Visual Studio 2010 window tab alignment is correct), but there is ItemsControl with HorizontalContentAlignment=Left in Visual Studio IDE that is found when tabs are above the code editor.

I’ve added ItemsControl to Tabs Studio controls tree:

TabsHost : ContentControl
|
 - TabsItemsControl : ItemsControl
   |
    - Tabs : Panel
     |
      - Tab : TabItem

With the default style:

<Style x:Key="DefaultTabsItemsControlStyle0" TargetType="TabsStudio:TabsItemsControl">
  <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>

In the next Tabs Studio release, horizontal tab alignment is Stretch by default in all scenarios:

Fixed stretch tab alignment in Visual Studio 2010

Fixed stretch tab alignment in Visual Studio 2010


If you prefer old left alignment, you will be able to set it with the following custom style:

<Style TargetType="TabsStudio:TabsItemsControl" BasedOn="{StaticResource DefaultTabsItemsControlStyle}">
  <Setter Property="HorizontalContentAlignment" Value="Left"/>
</Style>

February 25, 2011

Selected tab overlay

Filed under: Uncategorized — Tags: — Sergey Vlasov @ 3:23 pm

If you use custom colors for your tabs, for example, different colors for tabs from different projects, what do you do with the selected tab from a particular project? In the simplest setup you create a project coloring rule that excludes the selected tab and the selected tab looks the same no matter which project it belongs to:

Tab coloring rule for the WpfApplication5 project

Tab coloring rule for the WpfApplication5 project


Tab coloring rule for the WpfApplication6 project

Tab coloring rule for the WpfApplication6 project


Selected tab from the WpfApplication5 project

Selected tab from the WpfApplication5 project


Selected tab from the WpfApplication6 project

Selected tab from the WpfApplication6 project

If you get used to project colors, you may want to show selected tab’s project too. You can add an additional selected tab rule for each project:
Tab coloring rule for the selected tab in the WpfApplication5 project

Tab coloring rule for the selected tab in the WpfApplication5 project


Selected tab from the WpfApplication5 project showing project's color

Selected tab from the WpfApplication5 project showing project's color


The obvious disadvantage is that now you have to provide two coloring rules for each project (three rules if you use distinct color for the previously selected tab too). It would be nice to specify a selected tab overlay only once. Tabs Studio doesn’t currently support coloring rule overlays or rule combinations, but you can use a custom style for the TabInternals element to achieve the same result. First you change the tab coloring rules for the WpfApplication5 and WpfApplication6 projects to include the tab selected state:
Tab coloring rule for the WpfApplication5 project including the tab selected state

Tab coloring rule for the WpfApplication5 project including the tab selected state


Then add the following custom style:
Simple TabInternals overlay for the selected tab

Simple TabInternals overlay for the selected tab


Now this overlay works for all projects, but the red bar has some undesired padding around it. To remove this padding we remove Tab‘s padding, add TabNameGroup‘s left padding and add CloseTabButton‘s right padding (note that you need to uncomment one of the three CloseTabButton styles depending on your close tab button presentation setting):

<Style TargetType="TabsStudio:TabInternals" BasedOn="{StaticResource DefaultTabInternalsStyle}">
  <Setter Property="Margin" Value="-1,-1,-1,0"/>
  <Style.Triggers>
    <Trigger Property="IsTabSelected" Value="True">
      <Setter Property="Background">
      <Setter.Value>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
          <GradientStop Color="Red" Offset="0"/>
          <GradientStop Color="Transparent" Offset="0.3"/>
        </LinearGradientBrush>
      </Setter.Value>
      </Setter>
    </Trigger>
  </Style.Triggers>
</Style>

<Style TargetType="TabsStudio:Tab" BasedOn="{StaticResource DefaultTabStyle}">
  <Setter Property="Padding" Value="0,0,0,1"/>  
</Style>

<Style TargetType="TabsStudio:TabNameGroup" BasedOn="{StaticResource DefaultTabNameGroupStyle}">
  <Setter Property="Margin" Value="5,0,0,0"/>  
</Style>

<!--Close tab button: Show on selected tab-->
<Style TargetType="TabsStudio:CloseTabButton" BasedOn="{StaticResource DefaultCloseTabButtonStyle}">
  <Setter Property="Margin" Value="2,0,1,0"/>
  <Style.Triggers>
    <Trigger Property="IsTabSelected" Value="False">
      <Setter Property="Width" Value="4"/>
      <Setter Property="Visibility" Value="Hidden"/>
    </Trigger>
  </Style.Triggers>
</Style>

<!--Close tab button: Show on all tabs-->
<!--<Style TargetType="TabsStudio:CloseTabButton" BasedOn="{StaticResource DefaultCloseTabButtonStyle}">
  <Setter Property="Margin" Value="2,0,1,0"/>
</Style>-->

<!--Close tab button: Don't show-->
<!--<Style TargetType="TabsStudio:CloseTabButton" BasedOn="{StaticResource DefaultCloseTabButtonStyle}">
  <Setter Property="Width" Value="9"/>
  <Setter Property="Visibility" Value="Hidden"/>
  <Style.Triggers>
    <Trigger Property="IsTabSelected" Value="False">
      <Setter Property="Visibility" Value="Hidden"/>
    </Trigger>
  </Style.Triggers>
</Style>-->
Final selected tab overlay

Final selected tab overlay

November 18, 2010

Updating a style from add-ins

Filed under: Uncategorized — Tags: , — Sergey Vlasov @ 11:09 am

Continuing work on reducing necessity to manually craft a XAML style, I’ve added the ability to update a style from an add-in. For example, previously for SingleRow and Shaper add-ins you needed to copy sample styles from documentation and to use them together you needed to merge these styles. Newly updated SingleRow and Shaper programmatically apply default styles not cluttering the custom style:

Default SingleRow and Shaper styles

Default SingleRow and Shaper styles


The only thing missing from the sample Chrome style for Shaper is the grey line under the tabs, as currently only setters and triggers can be automatically merged, not control templates. To make it perfect, the following custom style can be used:

<Style TargetType="TabsStudio:TabsHost" BasedOn="{StaticResource DefaultTabsHostStyle}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type TabsStudio:TabsHost}">
       <StackPanel>  
        <Grid Panel.ZIndex="1">
          <Rectangle Width="{TemplateBinding Width}"
                     Height="{TemplateBinding Height}"
                     Fill="{TemplateBinding Background}"/>
          <Grid>
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="*"/>
              <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <ContentPresenter Grid.Column="0"/>
            <TabsStudioSingleRow:HiddenTabs Grid.Column="1" TabsPanel="{TemplateBinding ContentControl.Content}"/>
          </Grid>
        </Grid>
      <Border Height="1" Background="#93979D"/>
      </StackPanel>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>
The manually merged TabsHost style for SingleRow and Shaper

The manually merged TabsHost style for SingleRow and Shaper

Internally, the void UpdatePresentationStyles(string key, Presentation presentation) method was added to the TabsStudioExt.ITabsStudioEngine interface. It is possible to update styles dynamically, but right now SingleRow and Shaper do it only once in the OnConnection handler.

Triggers and setters for default Tabs Studio controls are added to the Styles property. For new controls (like TabsStudioSingleRow:HiddenTabs) a style resource and a default style usage are provided in the Presentation constructor:

private void UpdatePresentationStyle()
{
    TabsStudioExt.Presentation presentation = new TabsStudioExt.Presentation(
        LoadString("HiddenTabsStyle.xml"), LoadString("HiddenTabsUsage.xml"));
    {
        TabsStudioExt.PresentationStyle style = new TabsStudioExt.PresentationStyle();
        style.Triggers.Add(LoadString("TabTriggers.xml"));
        presentation.Styles.Add("TabsStudio:Tab", style);
    }
    {
        TabsStudioExt.PresentationStyle style = new TabsStudioExt.PresentationStyle();
        style.Setters.Add(LoadString("TabsHostTemplate.xml"));
        presentation.Styles.Add("TabsStudio:TabsHost", style);
    }
    engine.UpdatePresentationStyles("SingleRow", presentation);
}

The style parameter in the Presentation constructor can also add static resources for use in tab coloring rules. Theoretically it may be a custom brush or a generated color. These changes are included in the upcoming Tabs Studio release.

November 15, 2010

More tab coloring options

Filed under: Uncategorized — Tags: — Sergey Vlasov @ 12:00 pm

I’ve added Document paths regex and Custom conditions options to the Tab Coloring Rule dialog:

The Tab Coloring Rule dialog with new options

The Tab Coloring Rule dialog with new options

Document paths regex uses the newly added Paths tab item property consisting of document paths ending with ‘$’. For a tab “App .xaml .xaml.cs” Paths is something like “c:\Projects\WpfApplication1\app.xaml$c:\Projects\WpfApplication1\app.xaml.cs$”. If you want to set a color for all xaml and xaml.cs tabs, Document paths regex could be the following expression:

\.(xaml|xaml\.cs)\$

The Custom conditions option allows you to switch on tab item properties not listed in this dialog. For example, the MVCGroup add-in adds IsController and IsView attached tab properties. To color controller tabs you can use the following custom condition:

<Condition Binding="{Binding Path=(TabsStudioMvcGroup:Properties.IsController),
  RelativeSource={RelativeSource Self}}" Value="True"/>

Another example is for the case when you want to change the color of a tab in Visual Studio 2010 when tabs are not focused:

<Condition Binding="{Binding Path=IsGroupFocused, RelativeSource={RelativeSource Self}}" Value="False"/>

Download link: TabsStudio v2.1.7.

November 13, 2010

A color picker and a toolbar for AvalonStyleEditor

Filed under: Uncategorized — Tags: , — Sergey Vlasov @ 10:13 pm

I’ve added the ColorComb based color picker to the AvalonStyleEditor add-in:

Color Picker dialog in Tabs Studio

Color Picker dialog in Tabs Studio


When you open the color picker dialog, a color under the caret is loaded as the current color. After you select a new color in the dialog it overwrites the old color in the style editor. You can open the color picker from the editor toolbar and with the Ctrl+P keyboard shortcut.

I’ve also added the toolbar to the style editor that is present both on the Style page and in the Tab Coloring Rule dialog:

The editor toolbar on the Style page

The editor toolbar on the Style page


Download link: AvalonStyleEditor v1.0.1.

November 6, 2010

Tab coloring simplified

Filed under: Uncategorized — Tags: — Sergey Vlasov @ 4:37 pm

Trying to reduce necessity to manually craft a XAML style, I’ve added presentation parameters and tab coloring rules to Tabs Studio. While a custom XAML style allows seamless integration of different visual adornments together, it takes some time to make it right. Presentation parameters are a new layer between a default style and a custom style. It implements most common style options thus simplifying a custom XAML style.

Presentation is a new tab in Tabs Studio options and it replaces the Quick Style dialog. Font size, Close tab button style and Animation are now presentation options instead of a part of Quick Style generated style. Selected tab style, Previously selected tab and Non-document tab options from the old Quick Style dialog can now be represented as tab coloring rules:

Presentation parameters

Presentation parameters


Selected tab style XP rule

Selected tab style XP rule


Previously selected tab rule

Previously selected tab rule


Non-document tab rule

Non-document tab rule

A tab coloring rule has 5 filtering options and a definition for a tab background brush. Checked boolean options apply the rule to tabs with the corresponding property set to True (e.g. IsTabSelected), unchecked – to False and undefined – to all tabs. Regular expression options apply Regex.IsMatch with the corresponding property (e.g. TabName) when the regex is not empty (see Regular Expression Language Elements MSDN page for .NET regular expressions details).

Two more examples. The Forms rule applies to tabs with the name starting from Form when this tab is not selected and not previously selected. The WindowsFormsApplication1 project rule applies when tab’s project name contains WindowsFormsApplication1 and tab name doesn’t start from Form.

Forms rule

Forms rule


WindowsFormsApplication1 project rule

WindowsFormsApplication1 project rule

Tab background definition must be a Brush descendant. Different options to specify a color in XAML are listed on the Color documentation page.

Everything that presentation parameters do can be achieved in a XAML style. For example, the following style is equivalent to what a tab coloring rule generates internally:

<Style TargetType="TabsStudio:Tab" BasedOn="{StaticResource DefaultTabStyle}">
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding Path=IsTabSelected, RelativeSource={RelativeSource Self}}" Value="False"/>
                <Condition Binding="{Binding Path=IsPreviouslySelectedTab, RelativeSource={RelativeSource Self}}" Value="False"/>
                <Condition Binding="{Binding Path=IsDocument, RelativeSource={RelativeSource Self}}" Value="True"/>
                <Condition Binding="{Binding Path=TabName, RelativeSource={RelativeSource Self}, 
                		Converter={StaticResource RegexMatch},ConverterParameter='^Class'}" Value="True"/>
                <Condition Binding="{Binding Path=ProjectName, RelativeSource={RelativeSource Self}, 
                		Converter={StaticResource RegexMatch},ConverterParameter='^Windows'}" Value="True"/>
            </MultiDataTrigger.Conditions>
            <Setter Property="Background">
                <Setter.Value>
                     <SolidColorBrush Color="Red"/>
                </Setter.Value>
            </Setter>  
        </MultiDataTrigger>
    </Style.Triggers>
</Style>

There is one more convenience feature to set tab color. On the right click context menu there is now the Set color… command:

Set color context menu command

Set color context menu command

When adding a new rule using this command the options are pre-populated with the tab item parameters and when a matching rule(s) already exists then the Set Color choice dialog is presented:

Set color choce dialog

Set color choce dialog

Download link: TabsStudio v2.1.6.

October 20, 2010

Limiting number of tab rows

Filed under: Uncategorized — Tags: , — Sergey Vlasov @ 8:37 am

Due to popular demand and new tabs panel customization capabilities in Tabs Studio v2.1.2, I’ve created the SingleRow add-in that allows you to limit maximum number of tab rows and show remaining tabs in a drop-down list similar to default Visual Studio behavior:

A single row of tabs and the drop-down list of hidden tabs

A single row of tabs and the drop-down list of hidden tabs


To use SingleRow you need to set tabs layout to Wrap and apply the following style changes:
The Wrap tabs layout option

The Wrap tabs layout option

<Style TargetType="TabsStudio:TabsHost" BasedOn="{StaticResource DefaultTabsHostStyle}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type TabsStudio:TabsHost}">
        <Grid>
          <Rectangle Width="{TemplateBinding Width}"
                     Height="{TemplateBinding Height}"
                     Fill="{TemplateBinding Background}"/>
          <Grid>
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="*"/>
              <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <ContentPresenter Grid.Column="0"/>
            <TabsStudioSingleRow:HiddenTabs Grid.Column="1" TabsPanel="{TemplateBinding ContentControl.Content}"/>
          </Grid>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<Style TargetType="TabsStudio:Tab" BasedOn="{StaticResource DefaultTabStyle}">
  <Style.Triggers>
    <Trigger Property="TabsStudioSingleRow:Properties.IsTabHidden" Value="True">
      <Setter Property="Visibility"  Value="Collapsed"/>
    </Trigger>
  </Style.Triggers>
</Style>

<Style TargetType="TabsStudioSingleRow:HiddenTabs">
  <Setter Property="Content" Value=">"/>
  <Setter Property="Margin" Value="2,0,2,0"/>
  <Setter Property="VerticalAlignment" Value="Center"/>
  <Style.Triggers>
    <Trigger Property="TabsStudioSingleRow:Properties.IsHiddenTabs" Value="False">
      <Setter Property="Visibility"  Value="Collapsed"/>
    </Trigger>
  </Style.Triggers>
</Style>

This style adds the TabsStudioSingleRow:HiddenTabs button to open the drop-down list and binds it to the corresponding TabsPanel. SingleRow doesn’t actually hide tabs – it only sets the IsTabHidden property for them. The style above sets tab visibility based on this property. HiddenTabs button’s appearance is also defined in this style and the button is collapsed when there are no hidden tabs.

Tabs are hidden in the least recently used order and don’t automatically reappear even when space becomes available. Hidden tabs in the drop-down list are sorted alphabetically.

Default number of tab rows is 1, but you can change it in the SingleRow add-in options dialog:

SingleRow options dialog

SingleRow options dialog


Two rows of tabs and the hidden tabs list

Two rows of tabs and the hidden tabs list


Download link: SingleRow v1.0.0.

September 22, 2010

Visual Studio 2008 style explained

Filed under: Uncategorized — Tags: — Sergey Vlasov @ 8:16 am

Please, read the Overlapping sloped tabs post first for the general approach to tab shape customization. Let’s have a closer look at default tabs in Visual Studio 2008:

Tabs in Visual Studio 2008 (2x zoom)

Tabs in Visual Studio 2008 (2x zoom)


Below the tabs you can see the frame border that is overlapped by the selected tab. Tabs Studio window with tabs overlaps default tabs and two pixels of this border. In the Visual Studio 2008 style for Tabs Studio we are going to recreate overlapped top of the border:

<Border Height="2" BorderBrush="#69A1BF" BorderThickness="1,1,1,0" Background="White"/>

Selected tab needs to overlap the border. For that we increase z-index for tabs panel with background from 0 to 1 and later specify bottom margin for the selected tab as -2:

          <Grid Panel.ZIndex="1">
          ...
          <Trigger Property="IsTabSelected" Value="True">                           <!--Selected tab-->
            <Setter Property="Margin" Value="0,2,-9,-2"/>

Right margin for tabs is set to -9: it is amount of horizontal overlap between the adjacent tabs. With negative right margin the right border of tabs also overlaps the last tab in a row. To prevent overlap of the last tab in a row, we set buffering right margin of tabs to 10:

<Style TargetType="TabsStudio:Tabs" BasedOn="{StaticResource DefaultTabsStyle}">
  <Setter Property="Margin" Value="0,0,10,0"/>
</Style>

The selected tab has different shape, background and border comparing to default tabs. We create separate descriptions for these properties depending on the value of the IsTabSelected property. For the selected tab, the left side geometry is the following figure:

                <PathGeometry>
                  <PathFigure StartPoint="4 21">
                    <LineSegment Point="-16 21" IsStroked="false"/>
                    <LineSegment Point="-16 18.5" IsStroked="false"/>
                    <BezierSegment Point1="-1 1" Point2="-1 1" Point3="4 0" IsStroked="true" IsSmoothJoin="true"/>
                  </PathFigure>
                </PathGeometry>

The top bound of this figure is 0 – this is the rule for sides in Shaper. The right bound of this figure is 4 – making the slope overlap the tab contents by 4 pixels. An additional segment is automatically added by WPF from the end point to the start point to close the figure. For choosing Bezier control point values (Point1 and Point2) you can try the BezierExperimenter sample code from the “Applications = Code + Markup” book, chapter 28 (C# download, VB download).

The left bound of the right side figure is -3 – making the right side figure overlap the tab contents by 3 pixels (it doesn’t actually overlap the tab name because tab content has right margin 4):

                <PathGeometry>
                  <PathFigure StartPoint="-3 21">
                    <LineSegment Point="-1 21" IsStroked="false"/>
                    <LineSegment Point="-1 18.5" IsStroked="false"/>
                    <LineSegment Point="-1 2" IsStroked="true"/>
                    <LineSegment Point="-3 0" IsStroked="true"/>
                  </PathFigure>
                </PathGeometry>

The selected tab is 2 pixels higher than normal tabs – it has top margin 2 while normal tabs have top margin 4. Finally, selected tab font is bold and there is no close tab button:

<Style TargetType="TabsStudio:TabName" BasedOn="{StaticResource DefaultTabNameStyle}">
  <Style.Triggers>
    <Trigger Property="IsTabSelected" Value="True">
      <Setter Property="Control.FontWeight" Value="Bold"/>
    </Trigger>
  </Style.Triggers>
</Style>

<Style TargetType="TabsStudio:CloseTabButton" BasedOn="{StaticResource DefaultCloseTabButtonStyle}">
  <Setter Property="Visibility" Value="Collapsed"/>
</Style>

Here is the final Visual Studio 2008 style:

Visual Studio 2008 style in Tabs Studio (2x zoom)

Visual Studio 2008 style in Tabs Studio (2x zoom)

September 21, 2010

Overlapping sloped tabs

Filed under: Uncategorized — Tags: , — Sergey Vlasov @ 7:39 pm

I’ve extended Tabs Studio and created the Shaper add-in to make it possible to create customizable sloped tabs in Tabs Studio. To test the new capabilities, I tried to emulate default tabs of Visual Studio 2008 and Google Chrome. The results look almost exactly the same:

Tabs in Visual Studio 2008

Tabs in Visual Studio 2008


Visual Studio 2008 style in Tabs Studio

Visual Studio 2008 style in Tabs Studio


Tabs in Google Chrome

Tabs in Google Chrome


Chrome style in Tabs Studio

Chrome style in Tabs Studio

I’ll describe the new Visual Studio 2008 style in the next post. For now, let’s see what was added to Tabs Studio and how Shaper works.

TabsHost in Tabs Studio

Control tree now has a new root element TabsHost. The new root of the style specification is now:

TabsHost : ContentControl
|
 - Tabs : Panel (IsGroupSelected, IsGroupFocused for VS 2010, IsGroupWithLastActiveDocument for VS 2010)
   |
   ...

Introduction of TabsHost allows a tabs panel to be shifted and makes possible addition of other visual elements and controls at the tabs panel level. The DefaultTabsHostStyle is already a template using a rectangle behind the tabs to draw a background:

<Style x:Key="DefaultTabsHostStyle" TargetType="TabsStudio:TabsHost">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type TabsStudio:TabsHost}">
        <Grid>
          <Rectangle Width="{TemplateBinding Width}"
                     Height="{TemplateBinding Height}"
                     Fill="{TemplateBinding Background}"/>
          <ContentPresenter/>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Shaper

The first function of the Shaper add-in is to manage z-order of tabs so that tab #1 overlaps tab #2, tab #2 overlaps tab #3 and so on (default z-order is inverse). Shaper also sets z-index for the selected tab to overlap all others.

The second function of Shaper is the TabShape control. It is similar to the Border control, but specialized for trapezoid tabs. TabShape has LeftSide and RightSide properties of type Geometry plus Background Brush and Border Pen properties.

TabShape draws the central rectangular part of the trapezoid scaled to the tab content, draws the top border, draws sides and places tab content in the “middle”. Specifying negative and positive coordinates for left and right sides you control how sides overlap the content. All TabShape properties can be dynamically customized in style depending for example on whether tab is selected or not. Here is an example of the LeftSide geometry for the selected tab from the Visual Studio 2008 style (IsStroked property for each segment controls whether it drawn or not):

<Setter TargetName="TabShape" Property="LeftSide">
  <Setter.Value>
    <PathGeometry>
      <PathFigure StartPoint="4 21">
        <LineSegment Point="-16 21" IsStroked="false"/>
        <LineSegment Point="-16 18.5" IsStroked="false"/>
        <BezierSegment Point1="-1 1" Point2="-1 1" Point3="4 0" IsStroked="true" IsSmoothJoin="true"/>
      </PathFigure>
    </PathGeometry>
  </Setter.Value>
</Setter>

Download links

« Newer PostsOlder Posts »

Blog at WordPress.com.