如何在 WPF 中创建多个屏幕

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

我目前正在使用 MVVM 构建 WPF 应用程序,这就是我想要实现的目标。

所以,基本上当用户点击一个 Action 项时,他们可以看到该项的详细信息。一个项目可以有多个子项目,所以当用户点击子项目时,他们就可以看到子项目屏幕。他们可以单击标题上方的按钮返回上一屏幕。他们都应该使用相同的 viewModel cs 文件。 我是 WPF 和 C# 的新手,我做了一些研究,但对于它们都使用相同 viewModel 的情况,我找不到任何解决方案。我发现的是针对具有不同 viewModel 的不同视图。我感谢任何帮助。非常感谢!

wpf mvvm user-controls
1个回答
1
投票

您可以通过使用单个 ContentControl 并更改分配给其 Content 属性的模型来实现此目的。基础模型类如下所示:

class NavigationViewModel : BaseViewModel
{
    public NavigationViewModel PreviousView { get; set; }
    public FrameworkElement View { get; set; }
    public RelayCommand GoBackCommand { get; private set; }
    public string Name { get; private set; } 
    public RelayCommand<NavigationViewModel> ShowSubItem { get; private set; }

    public NavigationViewModel(Action<NavigationViewModel> updateCurrentView, string name)
    {
        Name = name; 
        ShowSubItem = new RelayCommand<NavigationViewModel>(view => updateCurrentView(view));
    }  
}

然后为每个视图创建特定的类

HomeViewModel(有 4 个操作项,我只创建了第一个)

class HomeViewModel : NavigationViewModel
{
    public ActionItem1ViewModel Action1 { get; private set; } 

    public HomeViewModel(Action<NavigationViewModel> updateCurrentView) : base(updateCurrentView, "Home")
    { 
        Action1 = new ActionItem1ViewModel(updateCurrentView)
        {
            PreviousView = this
        };
        PreviousView = null;
        View = new HomeView(); 
    }
}

和相关视图

  <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Button Content="Item #1" Command="{Binding ShowSubItem}" CommandParameter="{Binding Action1}"/>
    <Button Content="Item #2" Grid.Column="1"/>
    <Button Content="Item #3" Grid.Row="1"/>
    <Button Content="Item #4" Grid.Row="1" Grid.Column="1"/>
</Grid>

单个子项视图模型

class ActionItem1ViewModel : NavigationViewModel
{
    public Action1SubItemViewModel SubItem { get; private set; }

    public ActionItem1ViewModel(Action<NavigationViewModel> updateCurrentView) : base(updateCurrentView, "Item #1")
    {
        View = new Action1();
        SubItem = new Action1SubItemViewModel(updateCurrentView)
        {
            PreviousView = this
        };
    }
}

和相关视图

 <Button Content="Item #1" Command="{Binding ShowSubItem}" CommandParameter="{Binding SubItem}"/>

和子项详情查看模型

 class Action1SubItemViewModel : NavigationViewModel
{
    public Action1SubItemViewModel(Action<NavigationViewModel> updateCurrentView) : base(updateCurrentView, "Sub Item details")
    {
        View = new SubItem();
    }
}

和相关视图

 <TextBlock Text="details"/>

主窗口如下所示

 <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="100"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Button Content="{Binding CurrentView.PreviousView.Name}" Command="{Binding GoBackCommand}">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Visibility" Value="Visible"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding CurrentView.PreviousView}" Value="{x:Null}">
                        <Setter Property="Visibility" Value="Collapsed"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
    <ContentControl Grid.Row="1" Content="{Binding View}" DataContext="{Binding CurrentView}" Margin="50"/>
</Grid>

及其视图模型

 class MainViewModel : BaseViewModel
{
    private NavigationViewModel _currentView;
    public NavigationViewModel CurrentView
    {
        get => _currentView;
        set
        {
            _currentView = value;
            OnPropertyChanged();
        }
    }

    public RelayCommand GoBackCommand { get; private set; }

    public MainViewModel()
    {
        CurrentView = new HomeViewModel(UpdateCurrentView);
        GoBackCommand = new RelayCommand(() =>
        {
            CurrentView = CurrentView.PreviousView;
        });
    }

    private void UpdateCurrentView(NavigationViewModel viewModel)
    {
        CurrentView = viewModel;
    }
}

gif 链接

© www.soinside.com 2019 - 2024. All rights reserved.