This is a migrated thread and some comments may be shown as answers.

How to define different template for the DropDownMenuItem that appears inside the list of overflowing tab-control items

3 Answers 209 Views
TabControl
This is a migrated thread and some comments may be shown as answers.
Vladimir
Top achievements
Rank 1
Veteran
Vladimir asked on 09 Apr 2021, 01:48 PM

I have a RadTabControl and I want to enable the drop-down button "WhenNeeded" so that users can easily access the buttons in the tab control. I have three templates for the tab items (RadTabItem) which means I should have 3 templates as well for the drop-down buttons that appear in the drop-down list. 

There is a field called ItemDropDownContentTemplateSelector in RadTabControl and I created a template selector class like so:

    public class DropDownDisplayModeTemplateSelector: DataTemplateSelector
    {
        public override DataTemplate
            SelectTemplate(object item, DependencyObject container)
        {
            try
            {
                FrameworkElement element = container as FrameworkElement;
                Console.WriteLine("DropDownDisplayModeTemplateSelector: " + element.GetType().Name);
                if (element != null && item != null && item is TabItem)
                {
                    TabItem tabItem = item as TabItem;

                    switch (tabItem.TabItemStyle)
                    {
                        case TabItemStyle.Title:
                            return element.FindResource("TitleDropDownModeDataTemplate") as DataTemplate;

                        case TabItemStyle.Button:
                            return element.FindResource("ButtonDropDownModeDataTemplate") as DataTemplate;

                        case TabItemStyle.GroupOfButtons:
                            return element.FindResource("GroupOfButtonsDropDownModeDataTemplate") as DataTemplate;

                        default:
                            return element.FindResource("ButtonDropDownModeDataTemplate") as DataTemplate;
                    }
                }
                else
                    return null;
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }
    }

 

However, finding the DataTemplates with element.FindResource() method doesn't work because the container element is of type "DropDownMenuItem" which of course is not the element where my data templates are defined.

I have them defined in the top level Grid element like so:

<Grid>
        <Grid.Resources>
            <ResourceDictionary>

                <DataTemplate x:Key="TitleDropDownModeDataTemplate">
                    <TextBlock
                        HorizontalAlignment="Left"
                            VerticalAlignment="Center"
                            Margin="4"
                            Grid.Column="1"
                            Text="TitleDropDownModeDataTemplate" />
                </DataTemplate>

                <DataTemplate x:Key="ButtonDropDownModeDataTemplate">
                    <TextBlock
                        HorizontalAlignment="Left"
                            VerticalAlignment="Center"
                            Margin="4"
                            Grid.Column="1"
                            Text="ButtonDropDownModeDataTemplate" />
                </DataTemplate>

                <DataTemplate x:Key="GroupOfButtonsDropDownModeDataTemplate">
                    <TextBlock
                        HorizontalAlignment="Left"
                            VerticalAlignment="Center"
                            Margin="4"
                            Grid.Column="1"
                            Text="GroupOfButtonsDropDownModeDataTemplate" />
                </DataTemplate>

                <models:DropDownDisplayModeTemplateSelector x:Key="myDropDownDisplayModeTemplateSelector"/>
            </ResourceDictionary>
        </Grid.Resources>
        
        <telerik:RadTabControl

           ItemsSource="{Binding TabItems}"

           ItemDropDownContentTemplateSelector="{StaticResource myDropDownDisplayModeTemplateSelector}"
            DropDownDisplayMode="WhenNeeded">
</Grid>

In this case what should I do, hack the way top to the Grid's resources or I have done something wrong in defining my drop-down template selector?

3 Answers, 1 is accepted

Sort by
0
Dinko | Tech Support Engineer
Telerik team
answered on 14 Apr 2021, 11:27 AM

Hi Vladimir,

Thank you for the provided code snippet.

The custom templates are declared in the resources of the parent grid. That is why you can't get them. What you can try is to declare the custom styles in the App.xaml file. Then you can reach them from any file in the project. The following code snippet demonstrates what I have in mind.

. . . . . . . .
switch (tabItem.TabItemStyle)
                    {
                        case TabItemStyle.Title:
                            return Application.Current.Resources["TitleDropDownModeDataTemplate"] as DataTemplate;
 . . . . . . .

I hope this approach will work for you.

Regards,
Dinko
Progress Telerik

Тhe web is about to get a bit better! 

The Progress Hack-For-Good Challenge has started. Learn how to enter and make the web a worthier place: https://progress-worthyweb.devpost.com.

0
Vladimir
Top achievements
Rank 1
Veteran
answered on 16 Apr 2021, 12:51 PM

That certainly does the job though my chief programmer might not agree to put resources in the main App.xaml file.

And of course without this property being set: DropDownDisplayMemberPath

0
Dinko | Tech Support Engineer
Telerik team
answered on 21 Apr 2021, 08:14 AM

Hello Vladimir,

Thank you for sharing this. I have searched for a way to make it work and I think I found a solution. What you can try is to declare the custom templates in the resources of the DropDownMenu. You can do that by using the DropDownMenyStyle property of the RadTabControl.

 xmlns:tabControl="clr-namespace:Telerik.Windows.Controls.TabControl;assembly=Telerik.Windows.Controls.Navigation"

<telerik:RadTabControl x:Name="tabControl" 
                        ItemDropDownContentTemplateSelector="{StaticResource MyTemplateSelector}" Width="305" DropDownDisplayMode="WhenNeeded" >
    <telerik:RadTabControl.DropDownStyle>
        <Style TargetType="tabControl:DropDownMenu">              
            <Style.Resources>
                <DataTemplate x:Key="TitleDropDownModeDataTemplate">
                    <TextBlock
                HorizontalAlignment="Left"
                    VerticalAlignment="Center"
                    Margin="4"
                    Grid.Column="1"
                    Text="My Text" />
                </DataTemplate>
                <DataTemplate x:Key="ButtonDropDownModeDataTemplate">
                    <TextBlock
                HorizontalAlignment="Left"
                    VerticalAlignment="Center"
                    Margin="4"
                    Grid.Column="1"
                    Text="ButtonDropDownModeDataTemplate" />
                </DataTemplate>
            </Style.Resources>
        </Style>
    </telerik:RadTabControl.DropDownStyle>
 . . . . .

Then in the SelectTemplate method, you can get the DropDownMenu using our ParentOfType<T>() extension method. From the Style.Resources property you can access the custom templates.

public class MyTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var dropDownMenu = container.ParentOfType<DropDownMenu>();
        var str = item.ToString();
        if(str.StartsWith("W"))
        {
            return dropDownMenu.Style.Resources["TitleDropDownModeDataTemplate"] as DataTemplate;
        }
        
        return dropDownMenu.Style.Resources["ButtonDropDownModeDataTemplate"] as DataTemplate; ;
    }
}

As a side note, ignore the if clause in the above method. I have used dummy data to apply different templates. You can use your own custom logic here.

I hope this approach will work for you.

Regards,
Dinko
Progress Telerik

Тhe web is about to get a bit better! 

The Progress Hack-For-Good Challenge has started. Learn how to enter and make the web a worthier place: https://progress-worthyweb.devpost.com.

Tags
TabControl
Asked by
Vladimir
Top achievements
Rank 1
Veteran
Answers by
Dinko | Tech Support Engineer
Telerik team
Vladimir
Top achievements
Rank 1
Veteran
Share this question
or