WPF MVVM: Как загрузить представления «по требованию» без использования подключаемой архитектуры? - PullRequest
4 голосов
/ 25 июля 2011

У меня есть Outlook, подобный интерфейсу WPF с навигацией слева, панелью инструментов вверху и строкой состояния внизу, все в пределах DockPanel.

«Основная» область приложения находится в пределах DataGrid, который является LastChild и поэтому заполняет оставшееся пространство, и в настоящее время выглядит так:

    <Grid DockPanel.Dock="Right">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
        </Grid.RowDefinitions>
        <views:View1 Grid.Column="0" Grid.Row="0"/>
        <views:View2 Grid.Column="0" Grid.Row="0"/>
        <views:View3 Grid.Column="0" Grid.Row="0"/>
        <views:View4 Grid.Column="0" Grid.Row="0"/>
    </Grid>   

Все эти представления являются пользовательскими элементами управления, которые имеют свои собственные модели ViewModel со свойством Visibility, привязанным к свойству в его ViewModel и управляемым выбранными областями навигации. Когда элемент панели навигации выбран, основная ViewModel отправляет сообщение в ViewModels представлений, и после получения сообщения ViewModel представлений устанавливает свои свойства Visibility соответственно ...

Теперь, это работает нормально, но не чувствует себя хорошо, так как все ViewModel этих представлений создаются при запуске приложения, а не когда выбирается соответствующая панель навигации, поднимающая вопросы о производительности и использовании памяти ...

У меня вопрос: есть ли способ загрузки каждого вида и его ViewModel «по требованию», когда выбрана соответствующая панель навигации, и выгрузка этих видов и ViewModel, когда выбрана другая панель навигации, без обращения к PRISM / MEF или какая-то другая архитектура плагинов ... и, в более общем смысле, как бы вы подошли к созданию такого приложения с несколькими представлениями / моделями представления, "встроенными" в основное представление?

1 Ответ

8 голосов
/ 25 июля 2011

Вот что я делаю:

Сначала, в вашей основной ViewModel (той, которая обслуживает главное окно), добавьте свойство Content:

object _content;
public object Content
{
    get { return _content; }
    set
    {
        _content = value;
        RaisePropertyChanged("Content");
    }
}

Когда пользователь переключается с вида на вид, присвойте свойству Content значение соответствующего ViewModel для выбранного им вида.

В главном окне вы можете отобразить текущую Content ViewModel, используя ContentControl:

<ContentControl Content="{Binding Content}" />

... и где-то выше этого, определите DataTemplate для каждой из различных моделей представления, для которых Content может быть установлено:

<DataTemplate DataType="{x:Type vm:FooViewModel}">
    <my:FooUserControl />
</DataTemplate>

<DataTemplate DataType="{x:Type vm:BarViewModel}">
    <my:BarUserControl />
</DataTemplate>

Таким образом, теперь ContentControl будет отвечать за инициализацию и отображение каждого из ваших пользовательских элементов управления в зависимости от того, какая ViewModel в данный момент «активна».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...