Jak zachować stan kontroli w elementach karty w TabControl

Jestem nowicjuszem w WPF, próbując zbudować projekt zgodny z zaleceniami znakomitego artykułu Josh SmithaWzorzec projektowy model-widok-widok.

Używając przykładowego kodu Josh'a jako podstawy, stworzyłem prostą aplikację, która zawiera wiele „obszarów roboczych”, z których każda reprezentowana jest przez kartę w TabControl. W mojej aplikacji obszar roboczy jest edytorem dokumentów, który umożliwia manipulowanie dokumentem hierarchicznym za pomocą kontrolki TreeView.

Chociaż udało mi się otworzyć wiele obszarów roboczych i wyświetlić ich zawartość dokumentu w powiązanej kontrolce TreeView, stwierdzam, że TreeView „zapomina” o swoim stanie podczas przełączania między kartami. Na przykład, jeśli TreeView w Tab1 jest częściowo rozwinięty, po przełączeniu na Tab2 i powrocie do Tab1 zostanie wyświetlony jako całkowicie zwinięty. To zachowanie wydaje się mieć zastosowanie do wszystkich aspektów stanu sterowania dla wszystkich elementów sterujących.

Po kilku eksperymentach zdałem sobie sprawę, że mogę zachować stan wewnątrz elementu TabItem, jawnie wiążąc każdą właściwość stanu sterowania z dedykowaną właściwością podstawowego ViewModel. Wydaje się jednak, że jest to dużo dodatkowej pracy, gdy chcę, aby wszystkie moje kontrolki zapamiętały swój stan podczas przełączania między obszarami roboczymi.

Zakładam, że brakuje mi czegoś prostego, ale nie jestem pewien, gdzie szukać odpowiedzi. Wszelkie wskazówki byłyby bardzo mile widziane.

Dzięki, Tim

Aktualizacja:

Zgodnie z żądaniem spróbuję opublikować kod pokazujący ten problem. Ponieważ jednak dane leżące u podstaw TreeView są złożone, opublikuję uproszczony przykład, który pokazuje te same symbole. Oto XAML z głównego okna:

<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>

Powyższy XAML poprawnie wiąże się z ObservableCollection DocumentViewModel, gdzie każdy członek jest prezentowany za pomocą DocumentView.

Dla uproszczenia tego przykładu usunąłem TreeView (wspomniany powyżej) z DocumentView i zastąpiłem go TabControl zawierającym 3 stałe zakładki:

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

W tym scenariuszu nie ma powiązania między DocumentView a DocumentViewModel. Gdy kod jest uruchamiany, wewnętrzny kontroler TabControl nie jest w stanie zapamiętać jego wyboru, gdy zewnętrzny tabControl jest przełączany.

Jeśli jednak jawnie powiązam wewnętrzną właściwość SelectedIndex TabControl ...

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

... do odpowiedniej sztucznej właściwości w DocumentViewModel ...

public int SelecteDocumentIndex { get; set; }

... wewnętrzna karta jest w stanie zapamiętać jej wybór.

Rozumiem, że mogę skutecznie rozwiązać mój problem, stosując tę ​​technikę do każdej właściwości wizualnej każdej kontroli, ale mam nadzieję, że istnieje bardziej eleganckie rozwiązanie.

questionAnswers(6)

yourAnswerToTheQuestion