Wpf 使用棱镜动态地向 tabcontrol 添加更多视图

Wpf adding more views to tabcontrol dynamically with prism

我正在寻找如何设计我需要的结构的提示或方向,因为它有点棘手。我正在使用 MVVM 和 Prism。

我有 2 个区域,一个有 2 个按钮和一个选项卡控件区域。单击 button1 后,我想将 3 个视图作为选项卡注入到 tabcontrol 中。单击 button2 后,我想从 button1 中删除选项卡(但保留数据)并再次注入 3 个视图作为 tabcontrol 中的选项卡。棘手的部分来了 :-),这应该是动态发生的,button1 和 button2 的 3 个视图中有 2 个基于相同的 view/viewmodel。

我很感激我能得到的一切:-D

您应该能够使用 ViewModel 优先方法执行此操作。这是一种快速而肮脏的方法,请在您方便时清理它。

View/ViewModel结构:

View1 - ViewModel1 : IViewModel

View2 - ViewModel2:IViewModel

View3 - ViewModel3:IViewModel

IViewModel 需要 "Content" 字符串 属性

MainWindow.xaml

<Window x:Class="SFQ1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SFQ1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:ViewModel1}">
            <local:View1/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:ViewModel2}">
            <local:View2/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:ViewModel3}">
            <local:View3/>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
        <TabControl Grid.Row="0" ItemsSource="{Binding VmObservable}">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Content}"/>
                </DataTemplate>
            </TabControl.ItemTemplate>
            <TabControl.ContentTemplate>
                <DataTemplate>
                    <ContentControl Content="{Binding}">
                    </ContentControl>
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>
        <Button Grid.Row="1" Margin="10,0,0,0" Width="100" Content="1" 
                HorizontalAlignment="Left" Command="{Binding SetOneCommand}"/>
        <Button Grid.Row="1" Margin="130,0,0,0" Width="100" Content="2" 
                HorizontalAlignment="Left" Command="{Binding SetTwoCommand}"/>
    </Grid>
</Window>

MainViewModel.cs

public class MainViewModel : BindableBase
{
    private readonly List<IViewModel> _viewModelCollection;

    private ObservableCollection<IViewModel> _vmObservable;
    public ObservableCollection<IViewModel> VmObservable
    {
        get { return _vmObservable; }
        set
        {
            SetProperty(ref _vmObservable, value);
            RaisePropertyChanged();
        }
    }


    private IViewModel _activeVm;
    public IViewModel ActiveVm
    {
        get { return _activeVm; }
        set
        {
            SetProperty(ref _activeVm, value);
            RaisePropertyChanged();
        }
    }

    public DelegateCommand SetOneCommand { get; set; }
    public DelegateCommand SetTwoCommand { get; set; }

    public MainViewModel()
    {
        SetOneCommand = new DelegateCommand(SetOne);
        SetTwoCommand = new DelegateCommand(SetTwo);
        VmObservable = new ObservableCollection<IViewModel>();

        _viewModelCollection = new List<IViewModel>()
        {
            new ViewModel1(),
            new ViewModel2(),
            new ViewModel3()
        };
    }

    private void SetOne()
    {
        VmObservable.Clear();
        VmObservable.Add(GetViewModel(typeof(ViewModel1)));
        VmObservable.Add(GetViewModel(typeof(ViewModel2)));
        VmObservable.Add(GetViewModel(typeof(ViewModel3)));
    }

    private void SetTwo()
    {
        VmObservable.Clear();
        VmObservable.Add(GetViewModel(typeof(ViewModel2)));
        VmObservable.Add(GetViewModel(typeof(ViewModel3)));
    }

    private IViewModel GetViewModel( Type viewModelType )
    {
        return _viewModelCollection.Find(x => x.GetType().Equals(viewModelType));
    }
}