Я новичок в WPF и пытаюсь создать проект, который следует рекомендациям отличной статьи Джоша Смита, описывающей Шаблон проектирования модель-представление-модель просмотра.
Используя образец кода Джоша в качестве основы, я создал простое приложение, которое содержит ряд «рабочих пространств», каждое из которых представлено вкладкой в TabControl. В моем приложении рабочая область - это редактор документов, который позволяет управлять иерархическим документом с помощью элемента управления TreeView.
Хотя мне удалось открыть несколько рабочих пространств и просмотреть содержимое их документов в связанном элементе управления TreeView, я обнаружил, что TreeView «забывает» свое состояние при переключении между вкладками. Например, если TreeView в Tab1 частично развернут, он будет отображаться как полностью свернутый после переключения на Tab2 и возврата на Tab1. Такое поведение, по-видимому, применимо ко всем аспектам состояния элемента управления для всех элементов управления.
После некоторых экспериментов я понял, что могу сохранить состояние в TabItem, явно привязав каждое свойство состояния элемента управления к выделенному свойству в базовой ViewModel. Однако это кажется большой дополнительной работой, когда я просто хочу, чтобы все мои элементы управления запоминали свое состояние при переключении между рабочими пространствами.
Полагаю, мне не хватает чего-то простого, но я не уверен, где искать ответ. Любое руководство будет очень признательно.
Спасибо, Тим
Обновлять:
По запросу я попытаюсь опубликовать код, демонстрирующий эту проблему. Однако, поскольку данные, лежащие в основе TreeView, являются сложными, я опубликую упрощенный пример, демонстрирующий те же симптомы. Вот XAML из главного окна:
<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>
Вышеупомянутый XAML правильно привязывается к ObservableCollection из DocumentViewModel, благодаря чему каждый член представлен через DocumentView.
Для простоты этого примера я удалил TreeView (упомянутый выше) из DocumentView и заменил его TabControl, содержащим 3 фиксированных вкладки:
<TabControl>
<TabItem Header="A" />
<TabItem Header="B" />
<TabItem Header="C" />
</TabControl>
В этом сценарии нет привязки между DocumentView и DocumentViewModel. Когда код запускается, внутренний TabControl не может запомнить свой выбор при переключении внешнего TabControl.
Однако, если я явно привяжу внутреннее свойство TabControl SelectedIndex ...
<TabControl SelectedIndex="{Binding Path=SelectedDocumentIndex}">
<TabItem Header="A" />
<TabItem Header="B" />
<TabItem Header="C" />
</TabControl>
... к соответствующему фиктивному свойству в DocumentViewModel ...
public int SelecteDocumentIndex { get; set; }
... внутренняя вкладка может запомнить свой выбор.
Я понимаю, что могу эффективно решить свою проблему, применив этот метод ко всем визуальным свойствам каждого элемента управления, но я надеюсь, что есть более элегантное решение.
ItemsSource
сDataTemplate
, похоже, что визуальное состояние элементов управления в шаблоне данных общий (!!!) среди элементов вкладки! - person Aviad P.   schedule 18.01.2010