WPF MVVM 导航视图。问题继续创建视图实例

问题描述 投票:0回答:1

我想要实现的是,当我单击按钮时,视图会切换。

但是,每当切换 Viewmodel 时,View Instance 都会继续创建。

我只想第一次创建和重用视图实例。

有没有一种常用且好的方法可以在不违反 MVVM 的情况下实现无代码隐藏?

App.xaml

<Application.Resources>
    <DataTemplate DataType="{x:Type vm:RedViewModel}">
        <v:RedUserControl/>
    </DataTemplate>

    <DataTemplate DataType="{x:Type vm:BlueViewModel}">
        <v:BlueUserControl/>
    </DataTemplate>
</Application.Resources>

MainWindow.xaml

<Window x:Class="NavigationView.MainWindow"
        xmlns:vm="clr-namespace:NavigationView.ViewModel">
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>
    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="60"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <StackPanel Grid.Row="0" Orientation="Horizontal">
            <Button Content="Red UserControl" Command="{Binding RedCommand}"/>
            <Button Content="Blue UserControl" Command="{Binding BlueCommand}"/>
        </StackPanel>

        <ContentControl Grid.Row="1" Content="{Binding ContentView}"/>
    </Grid>
</Window>

MainWindowViewModel.cs

namespace NavigationView.ViewModel
{
    public class MainWindowViewModel : ViewModelBase
    {
        private ViewModelManager _viewModelManager;

        private object _contentView;
        public object ContentView
        {
            get { return _contentView; }
            set { _contentView = value; OnPropertyChanged(); }
        }

        public ICommand RedCommand { get; set; }
        public void Red(object obj)
        {
            ContentView = _viewModelManager._redViewModel;
        }
        public ICommand BlueCommand { get; set; }
        public void Blue(object obj)
        {
            ContentView = _viewModelManager._blueViewModel;
        }

        public MainWindowViewModel()
        {
            _viewModelManager = new ViewModelManager();

            RedCommand = new RelayCommand<object>(Red);
            BlueCommand = new RelayCommand<object>(Blue);

            ContentView = _viewModelManager._redViewModel;
        }
    }
}

RedUserControl.xaml

<UserControl x:Class="NavigationView.View.RedUserControl"
             Background="Red">
    <Grid>
    </Grid>
</UserControl>

RedViewModel.cs

namespace NavigationView.ViewModel
{
    public class RedViewModel
    {
        public RedViewModel()
        {
        }
    }
}

BlueUserControl.xaml

<UserControl x:Class="NavigationView.View.BlueUserControl"
             Background="Blue">
    <Grid>
    </Grid>
</UserControl>

BlueViewModel.cs

namespace NavigationView.ViewModel
{
    public class BlueViewModel
    {
        public BlueViewModel()
        {
        }
    }
}

ViewModelManager.cs

namespace NavigationView.ViewModel
{
    public class ViewModelManager
    {
        public RedViewModel _redViewModel;
        public BlueViewModel _blueViewModel;

        public ViewModelManager()
        {
            _redViewModel = new RedViewModel();
            _blueViewModel = new BlueViewModel();
        }
    }
}

当你设置DataTemplate时,你发现了View Instance不断被创建的原因。

我已经在这个区域被困了几天了,所以我根本无法继续。

希望各位高手和有经验的人帮助我。

谢谢你

wpf mvvm
1个回答
0
投票

如果您只是通过

DataTemplate
提供视图,则无法重复使用它们。这是因为
DataTemplate
没有被重复使用。它是一个模板,指示 XAML 解析器必须创建什么对象。

你可以做的就是将视图本身定义为静态资源。请注意,该资源同一时间只能使用一次(

UIElement
的实例只能存在于可视化树中的一个位置):

<Application.Resources>
  <RedUserControl x:Key="RedUserControl" />
  <BlueUserControl x:Key="RedUserControl" />

  <DataTemplate DataType="{x:Type vm:RedViewModel}">
    <ContentControl Content="{StaticResource RedUserControl}" />
  </DataTemplate>

  <DataTemplate DataType="{x:Type vm:BlueViewModel}">
    <ContentControl Content="{StaticResource BlueUserControl}" />
  </DataTemplate>
</Application.Resources>
© www.soinside.com 2019 - 2024. All rights reserved.