53 votes

TabControl à Ajouter un Nouvel Onglet Bouton (+)

Quelle est la bonne façon d'ajouter un bouton " + " de l'onglet à la fin de tous les onglet éléments dans la barre d'onglets de contrôle onglet dans WPF.

  1. Il devrait fonctionner correctement avec plusieurs onglet lignes d'en-tête.
  2. Il devrait être à la fin de l'onglet tous les éléments
  3. Onglet de cyclisme devrait fonctionner correctement (Alt+Tab) c'est à dire le + tab doivent être ignorés.
  4. Je ne devrais pas avoir à modifier le code source de la collection je suis de liaison pour. c'est à dire le contrôle doivent être réutilisables.
  5. La Solution de travail avec MVVM

enter image description here

enter image description here

EDIT: Pour être plus précis, le bouton doit apparaître exactement comme un supplément de dernier onglet et non pas comme un bouton séparé quelque part sur la droite de l'onglet tous bande de lignes.

Je suis simplement à la recherche pour l'approche générale à le faire.

Google lance de nombreux exemples, mais si vous creusez un peu de deep aucun d'entre eux de satisfaire tous les cinq points.

Toute aide grandement appréciée.

N

37voto

NVM Points 2476

Une presque complète de la solution à l'aide de IEditableCollectionView:

ObservableCollection<ItemVM> _items;
public ObservableCollection<ItemVM> Items
{
    get
    {
        if (_items == null)
        {
            _items = new ObservableCollection<ItemVM>();
            var itemsView = (IEditableCollectionView)CollectionViewSource.GetDefaultView(_items);
            itemsView.NewItemPlaceholderPosition = NewItemPlaceholderPosition.AtEnd;
        }

        return _items;
    }
}

private DelegateCommand<object> _newCommand;
public DelegateCommand<object> NewCommand
{
    get
    {
        if (_newCommand == null)
        {
            _newCommand = new DelegateCommand<object>(New_Execute);
        }

        return _newCommand;
    }
}

private void New_Execute(object parameter)
{
    Items.Add(new ItemVM());
}
<DataTemplate x:Key="newTabButtonContentTemplate">
    <Grid/>
</DataTemplate>

<DataTemplate x:Key="newTabButtonHeaderTemplate">
    <Button Content="+"
        Command="{Binding ElementName=parentUserControl, Path=DataContext.NewCommand}"/>
</DataTemplate>

<DataTemplate x:Key="itemContentTemplate">
    <Grid/>
</DataTemplate>

<DataTemplate x:Key="itemHeaderTemplate">
    <TextBlock Text="TabItem_test"/>
</DataTemplate>

<vw:TemplateSelector x:Key="headerTemplateSelector"
                           NewButtonTemplate="{StaticResource newTabButtonHeaderTemplate}"
                           ItemTemplate="{StaticResource itemHeaderTemplate}"/>

<vw:TemplateSelector x:Key="contentTemplateSelector"
                            NewButtonTemplate="{StaticResource newTabButtonContentTemplate}"
                            ItemTemplate="{StaticResource itemContentTemplate}"/>

<TabControl ItemsSource="{Binding Items}"
        ItemTemplateSelector="{StaticResource headerTemplateSelector}"
        ContentTemplateSelector="{StaticResource contentTemplateSelector}"/>
public class TemplateSelector : DataTemplateSelector
{
    public DataTemplate ItemTemplate { get; set; }
    public DataTemplate NewButtonTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item == CollectionView.NewItemPlaceholder)
        {
            return NewButtonTemplate;
        }
        else
        {
            return ItemTemplate;
        }
    }
}

enter code here

Presque complet, car l'onglet cycle de ne pas sauter le " + " de l'onglet, et montrer de contenu vide (ce qui n'est pas grand, mais je peux vivre avec elle jusqu'à ce qu'une meilleure solution à venir... ).

1voto

Ingó Vals Points 1371

OK essayez ceci

Définir le ControlTemplate du TabControl comme ceci:

 <!-- Sets the look of the Tabcontrol. -->
<Style x:Key="TabControlStyle" TargetType="{x:Type TabControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabControl}">
                <Grid>
                    <!-- Upperrow holds the tabs themselves and lower the content of the tab -->
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>

La ligne supérieure de la grille serait le TabPanel mais vous ne le mettre que dans un StackPanel avec un bouton à la suite de la TabPanel, le style, la touche pour ressembler à un onglet

Maintenant le bouton créer une nouvelle TabItem (personnalisé créé un peut-être) et l'ajouter à la ObservableCollection des Onglets que vous avez comme l'Itemssource pour votre TabControl.

1) je pense que je sais ce que tu veux dire mais vous ne savez pas bien, me mettre à jour sur celui-ci

2 & 3) Il doit toujours apparaître à la fin, et ce n'est pas un onglet donc j'espère ne pas faire partie de l'onglet cyclisme

4) votre TabControl doit utiliser une ObservableCollection de TabItems comme Itemssource pour être averti quand un nouveau est ajouté/retiré

Espérons que cette aide.

EDIT: Ajout d'un peu de code

Le NewTabButton usercontrol .cs fichier

public partial class NewTabButton : TabItem
{
    public NewTabButton()
    {
        InitializeComponent();

        Header = "+";
    }
}

et la fenêtre principale:

public partial class Window1 : Window
{
    public ObservableCollection<TabItem> Tabs { get; set; }

    public Window1()
    {
        InitializeComponent();

        Tabs = new ObservableCollection<TabItem>();

        for (int i = 0; i < 20; i++)
        {
            TabItem tab = new TabItem();
            tab.Header = "TabNumber" + i.ToString();
            Tabs.Add(tab);
        }

        Tabs.Add(new NewTabButton());

        theTabs.ItemsSource = Tabs;
    }
}

Maintenant, nous devons trouver un moyen de le laisser apparaissent toujours bottme droit et ajouter de l'événement et de style pour elle ( la plus chanter est là comme un espace réservé ).

Je vais prendre un meilleur regard demain.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X