Customizing Dropdown Content in WPF HandyControl TabControl

67 Views Asked by At

I'm using the WPF HandyControl TabControl and I want to customize the content displayed in the dropdown when there are too many tabs to fit within the visible area. Currently, when the tab width exceeds the TabControl's visible area, the displayed content isn't what I expect. I've tried using ItemTemplate and DropDownContentTemplate, but it seems I'm not getting the desired results.

    <hc:TabControl
        IsAnimationEnabled="False"
        IsDraggable="False"
        IsTabFillEnabled="False"
        ItemsSource="{Binding DataSaves, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
        SelectedItem="{Binding SelectedDataSave, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
        <hc:TabControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock
                        Name="txt1"
                        Margin="6,0,0,0"
                        VerticalAlignment="Center"
                        Text="{Binding DisplayName}" />
                </StackPanel>
            </DataTemplate>
        </hc:TabControl.ItemTemplate>
        <hc:TabControl.ContentTemplate>
            <DataTemplate>
                <ContentPresenter Content="{Binding UserControl, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
            </DataTemplate>
        </hc:TabControl.ContentTemplate>
    </hc:TabControl>
1

There are 1 best solutions below

0
coffeeman13 On

I suggest to use ComboBox + ContentControl over the TabControl.

public interface IData
{
    string Label { get; }
}

public class DataWithList : IData
{
    public string Label {get; set;}
    public List<string> Items {get; set;}
}

public class DataWithStack : IData
{
    public string Label {get; set;}
    public Stack<string> Items {get; set;}
}

public class MyModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged; 

    public List<IData> Entries { get; set; }

    private IData m_selection;
    public IData Selection {
        get => m_selection; 
        set
        {
            m_selection = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Selection)));
        }
    }
}

and in your WPF,

<ComboBox ItemsSource="{Binding Entries}" SelectedItem="{Binding Selection, UpdateSourceTrigger=PropertyChanged}">
      <ComboBox.ItemTemplate>
        <DataTemplate>
          <TextBox Text="{Binding Label}"/>
        </DataTemplate>
      </ComboBox.ItemTemplate>
</ComboBox>
<ContentControl Content="{Binding Selection}"/>

and you define, the content template by using DataTemplate or DataTemplateSelector

<DataTemplate DataType="{x:Type DataWithList}">
      <TextBlock Text="DataWithList"/>
</DataTemplate>
<DataTemplate DataType="{x:Type DataWithStack}">
      <TextBlock Text="DataWithStack"/>
</DataTemplate>