Внедрение представлений на основе DataTemplate с помощью MVVM

У меня есть представление контейнера, которое выглядит примерно так

<UserControl x:Class="Views.ContainerView">
    <UserControl.Resources>
        <ResourceDictionary>
            <DataTemplate DataType="{x:Type viewmodels:AViewModel}">
                <views:MyView />
            </DataTemplate>
            <DataTemplate DataType="{x:Type viewmodels:BViewModel}">
                <views:MyView />
            </DataTemplate>
            <DataTemplate DataType="{x:Type viewmodels:CViewModel}">
                <views:MyView />
            </DataTemplate>
            <DataTemplate DataType="{x:Type viewmodels:DViewModel}">
                <views:MyView />
            </DataTemplate>
        </ResourceDictionary>
    </UserControl.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding Path=AvailableViewModels}" 
            SelectedItem="{Binding Path=CurrentViewModel}" 
            IsSynchronizedWithCurrentItem="True" />
        <ContentControl Content="{Binding Path=CurrentViewModel}" />
    </Grid>
</UserControl>

Все мои модели просмотра наследуют BaseViewModel, поэтому я превратил свое представление в это

<UserControl x:Class="Views.ContainerView">
    <UserControl.Resources>
        <ResourceDictionary>
            <DataTemplate DataType="{x:Type viewmodels:BaseViewModel}">
                <views:MyView />
            </DataTemplate>
        </ResourceDictionary>
    </UserControl.Resources>
    <StackPanel>
        <ListBox ItemsSource="{Binding Path=AvailableViewModels}" 
            SelectedItem="{Binding Path=CurrentViewModel}" 
            IsSynchronizedWithCurrentItem="True" />
        <ContentControl Content="{Binding Path=CurrentViewModel}" />
    </StackPanel>
</UserControl>

думая, что он создаст экземпляр только одного MyView и просто перепривязывает модель представления при изменении ListBox.SelectedItem. Я правильно понимаю это поведение? Является ли это предпочтительной практикой? Как я могу убедиться, что я не перегружаю память при переключении между представлениями?


person kenwarner    schedule 25.09.2009    source источник


Ответы (2)


Он создаст экземпляр нового MyView для каждой используемой вами модели представления. Если вы хотите повторно использовать свои пользовательские элементы управления, вы можете установить свойство DataContext для каждого пользовательского элемента управления.

person Pavel    schedule 21.10.2009

Чтобы расширить ответ Павла и уточнить, что происходит, когда с представлениями при изменении моделей представлений заключается в том, что новое представление будет создано для новой модели представления, а старое представление надеюсь будет собрано в мусор время.

Проблема в том, что иногда у нас будут представления, которые регистрируются на какое-то событие в коде позади (неслабые события), и это предотвратит сбор представления, и у вас возникнет утечка памяти.

Два подхода.

  1. Любая подписка на события в представлении кода программной части должна быть ослаблена (EventAggregator в PRISM), чтобы разрешить сборку мусора.
  2. Зарегистрируйте экземпляр представления в контейнере единства и разрешите его, когда вам нужно его повторно использовать. Прежде чем внедрять его в регион, просто обновите DataContext.

Надеюсь это поможет.

person Tri Q Tran    schedule 11.11.2010