AdvancedTabControl Template?

Docking/MDI for WPF Forum

Posted 2 years ago by Ethem Acar
Version: 22.1.3
Avatar

So I implemented TreeListBox with ItemTemplateSelector which was awesome I could style & build the content exactly like i wanted. Now I'm on the DockControls AdvancedTabControl and can't find anything how I can customize the tab content based on the class with a ItemTemplateSelector. I feel like its not possible? Only Icon & Title is customizable? My goal is to have Label - Icon - Label.

[Modified 2 years ago]

Comments (9)

Posted 2 years ago by Ethem Acar
Avatar

So I tried this with no luck :D

 <dockingViewModels:TabControlTemplateSelector x:Key="TabControlTemplateSelector">
        <dockingViewModels:TabControlTemplateSelector.GlobalTemplate>
            <DataTemplate>
                <Grid ShowGridLines="False">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Label
                        Grid.Column="0"
                        Margin="0,0,5,0"
                        Padding="0,0,0,0"
                        Content="Test"
                        FontSize="10"/>
                </Grid>
            </DataTemplate>
 </dockingViewModels:TabControlTemplateSelector.GlobalTemplate>

<Style x:Key="TabControlStyle" TargetType="docking:AdvancedTabControl">
  <Setter Property="ItemTemplateSelector" Value="{StaticResource TabControlTemplateSelector}" />
</Setter>
Posted 2 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

The AdvancedTabItem control inherits the native WPF TabItem control, but its Template is much more complex than TabItem's.  It has additional elements like buttons and context display elements.  There is a ContentPresenter in the Template that is bound to Header/HeaderTemplate, however it appears it was missing a binding to HeaderTemplateSelector too.  We will add that for the upcoming maintenance release.

If you set a single DataTemplate to the tab control's ItemTemplate property instead, does that work?


Actipro Software Support

Posted 2 years ago by Ethem Acar
Avatar

If you set a single DataTemplate to the tab control's ItemTemplate property instead, does that work?

Yes it does work.

Sadly different class types need different contents for my tabs so I will wait for selectors fix release.

Posted 2 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Ok good, then the update we made for the next maintenance release should work for you since ItemTemplate is currently wired up in a way ItemTemplateSelector previously was not.


Actipro Software Support

Posted 1 year ago by Ethem Acar
Avatar

Hi,

After 4 months I started developing on my project again.
I updated the NuGet package to version 22.1.4 yet ItemTemplateSelector for TabControlStyle still seems to be not working. When I set a breakpoint to TabControlTemplateSelector it never hits.

My project code or full source here (https://easyupload.io/4je59w):

        <selectors:TabControlTemplateSelector x:Key="TabControlTemplateSelector">
            <selectors:TabControlTemplateSelector.HelloDocumentTabTemplate>
                <DataTemplate>
                    <Grid ShowGridLines="False">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Label
                            Grid.Column="0"
                            Margin="0,0,5,0"
                            Padding="0,0,0,0"
                            Content="Hello from Template!"
                            FontSize="10" />
                    </Grid>
                </DataTemplate>
            </selectors:TabControlTemplateSelector.HelloDocumentTabTemplate>
            <selectors:TabControlTemplateSelector.WelcomeDocumentTabTemplate>
                <DataTemplate>
                    <Grid ShowGridLines="False">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Label
                            Grid.Column="0"
                            Margin="0,0,5,0"
                            Padding="0,0,0,0"
                            Content="Welcome from Template!"
                            FontSize="10"/>
                    </Grid>
                </DataTemplate>
            </selectors:TabControlTemplateSelector.WelcomeDocumentTabTemplate>
        </selectors:TabControlTemplateSelector>
        <Style x:Key="TabControlStyle" TargetType="docking:AdvancedTabControl">
            <Setter Property="ItemTemplateSelector" Value="{StaticResource TabControlTemplateSelector}" />
        </Style>
 <docking:DockSite
            x:Name="DockSite"
            Grid.Row="0"
            CanDocumentWindowsFloat="True"
            DocumentItemContainerStyle="{StaticResource DocumentWindowStyle}"
            DocumentItemTemplateSelector="{StaticResource DocumentWindowTemplateSelector}"
            DocumentItemsSource="{Binding DocumentWindows}">
            <docking:SplitContainer Orientation="Vertical">

                <docking:Workspace>
                    <docking:TabbedMdiHost
                        ContainersHaveNewTabButtons="True"
                        TabControlStyle="{StaticResource TabControlStyle}" />
                </docking:Workspace>
                <docking:TabbedMdiContainer />

            </docking:SplitContainer>
</docking:DockSite>
public class TabControlTemplateSelector : DataTemplateSelector
    {
        public DataTemplate? HelloDocumentTabTemplate { get; set; }
        public DataTemplate? WelcomeDocumentTabTemplate { get; set; }
        public override DataTemplate? SelectTemplate(object item, DependencyObject container)
        {
            return item switch
            {
                HelloDocumentWindowViewModel => HelloDocumentTabTemplate,
                WelcomeDocumentWindowViewModel => WelcomeDocumentTabTemplate,
                _ => null
            };
        }
    }

[Modified 1 year ago]

Posted 1 year ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

The root DockSite.DocumentItemTemplateSelector property will override the TabControlStyle's ItemTemplateSelector property.  If you change your DockSite attribute to this, it should work:

<docking:DockSite ...
  DocumentItemTemplateSelector="{StaticResource TabControlTemplateSelector}"
  ... >


Actipro Software Support

Posted 1 year ago by Ethem Acar
Avatar

I'm confused, what I'm trying to do is modify the tab look itself not the tab document content.

DocumentItemTemplateSelector

Is for the tab document content template which I'm setting correctly in my example project.

This is what I'm trying to achieve:

https://storage.googleapis.com/openscreenshot/_%2FV%2FJ/pKBJWEJV_.png

Which is possible with:

    <DataTemplate x:Key="TemplateTab">
            <Grid ShowGridLines="False">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <Label
                    Grid.Column="0"
                    Margin="0,0,5,0"
                    Padding="0,0,0,0"
                    Content="Modified with template"
                    FontSize="10"/>
            </Grid>
        </DataTemplate>

<Setter Property="ItemTemplate" Value="{StaticResource TemplateTab}"></Setter>

But not with ItemTemplateSelector to give different look for tabs based on class.

Answer - Posted 1 year ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Ahh thank you, I see now.  What's happening is that TabbedMdiHost defines a default TabItemContainerStyle of this:

<Style TargetType="docking:AdvancedTabItem">
	<Setter Property="Header" Value="{Binding TabTextResolved}" />
	<Setter Property="HeaderTemplate">
		<Setter.Value>
			<DataTemplate>
				<TextBlock Text="{Binding Converter={StaticResource TitleConverter}}" TextTrimming="CharacterEllipsis" TextWrapping="NoWrap" VerticalAlignment="Center" />
			</DataTemplate>
		</Setter.Value>
	</Setter>
</Style>

That puts the tab text in the Header property and supplies a HeaderTemplate.  

Your TabControlTemplateSelector is getting pushed down to be the HeaderTemplateSelector, however the presence of a HeaderTemplate will override a HeaderTemplateSelector, so the selector is never called into.

To get it working, add this to Window.Resources:

<Style x:Key="DockingWindowAdvancedTabItemStyle" TargetType="docking:AdvancedTabItem">
    <Setter Property="Header" Value="{Binding DataContext}" />
    <Setter Property="HeaderTemplateSelector" Value="{StaticResource TabControlTemplateSelector}" />
</Style>

That new Style removes the HeaderTemplate setter and adds one for HeaderTemplateSelector in its place.  Then reference it in your TabbedMdiHost like this:

TabItemContainerStyle="{StaticResource DockingWindowAdvancedTabItemStyle}"

After that, the view model will be properly fed into your selector and you'll see the dynamic templates working.


Actipro Software Support

Posted 1 year ago by Ethem Acar
Avatar

Thank you very much,

Indeed, it exactly worked like you explained and the end result is as i expected.

https://storage.googleapis.com/openscreenshot/F%2Fl%2F-/2TCuKt-lF.png

The latest build of this product (v24.1.2) was released 7 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.