38 votes

Comment préserver l'état du contrôle dans les éléments de l'onglet d'un TabControl ?

Je suis un nouveau venu dans le monde de WPF, et je tente de construire un projet qui suit les recommandations de l'excellent article de Josh Smith décrivant Le modèle de conception Modèle-Vue-Vue-Modèle .

En utilisant l'exemple de code de Josh comme base, j'ai créé une application simple qui contient un certain nombre d'"espaces de travail", chacun étant représenté par un onglet dans un TabControl. Dans mon application, un espace de travail est un éditeur de document qui permet de manipuler un document hiérarchique via un contrôle TreeView.

Bien que j'aie réussi à ouvrir plusieurs espaces de travail et à afficher le contenu de leurs documents dans le contrôle TreeView lié, je constate que le TreeView "oublie" son état lorsqu'on passe d'un onglet à l'autre. Par exemple, si l'arborescence de l'onglet 1 est partiellement développée, elle sera affichée comme étant entièrement réduite après être passée à l'onglet 2 et être revenue à l'onglet 1. Ce comportement semble s'appliquer à tous les aspects de l'état des contrôles pour tous les contrôles.

Après quelques expérimentations, j'ai réalisé que je pouvais préserver l'état d'un TabItem en liant explicitement chaque propriété d'état du contrôle à une propriété dédiée du ViewModel sous-jacent. Cependant, cela semble représenter beaucoup de travail supplémentaire, alors que je veux simplement que tous mes contrôles se souviennent de leur état lorsque je passe d'un espace de travail à un autre.

Je suppose qu'il me manque quelque chose de simple, mais je ne sais pas où chercher la réponse. Tout conseil serait le bienvenu.

Merci, Tim

Mise à jour :

Comme demandé, je vais essayer de poster un code qui démontre ce problème. Cependant, comme les données qui sous-tendent le TreeView sont complexes, je vais publier un exemple simplifié qui présente les mêmes symptômes. Voici le XAML de la fenêtre principale :

<TabControl IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Path=Docs}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <ContentPresenter Content="{Binding Path=Name}" />
        </DataTemplate>
    </TabControl.ItemTemplate>

    <TabControl.ContentTemplate>
        <DataTemplate>
            <view:DocumentView />
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

Le XAML ci-dessus se lie correctement à une ObservableCollection de DocumentViewModel, dont chaque membre est présenté via un DocumentView.

Pour la simplicité de cet exemple, j'ai supprimé le TreeView (mentionné ci-dessus) du DocumentView et l'ai remplacé par un TabControl contenant 3 onglets fixes :

<TabControl>
    <TabItem Header="A" />
    <TabItem Header="B" />
    <TabItem Header="C" />
</TabControl>

Dans ce scénario, il n'y a pas de liaison entre le DocumentView et le DocumentViewModel. Lorsque le code est exécuté, le contrôle d'onglet interne est incapable de se souvenir de sa sélection lorsque le contrôle d'onglet externe est changé.

Cependant, si je lie explicitement la propriété SelectedIndex du contrôle d'onglet interne...

<TabControl SelectedIndex="{Binding Path=SelectedDocumentIndex}">
    <TabItem Header="A" />
    <TabItem Header="B" />
    <TabItem Header="C" />
</TabControl>

... à une propriété fictive correspondante sur le DocumentViewModel ...

public int SelecteDocumentIndex { get; set; }

... l'onglet intérieur est capable de se souvenir de sa sélection.

Je comprends que je peux résoudre efficacement mon problème en appliquant cette technique à chaque propriété visuelle de chaque contrôle, mais j'espère qu'il existe une solution plus élégante.

1voto

jbe Points 4629

L'exemple d'application Writer de l Cadre d'application WPF (WAF) montre comment résoudre votre problème. Il crée un nouveau UserControl pour chaque TabItem. Ainsi, l'état est préservé lorsque l'utilisateur change l'onglet actif.

-1voto

Rahul W Points 340

J'ai publié une réponse à une question similaire. Dans mon cas, la création manuelle des TabItems a résolu le problème de la création répétée de la vue. Vérifiez ici

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