wpf 如何在 MainWindow 上显示不同的视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29976262/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:06:51  来源:igfitidea点击:

How to display different views on MainWindow

wpfmvvm

提问by Jagd

So I followed a video online that showed me how to implement MVVM in a WPF application. Please note that I am a newbie when it comes to both of them.

所以我关注了一个在线视频,该视频向我展示了如何在 WPF 应用程序中实现 MVVM。请注意,当涉及到它们时,我是新手。

I have the following classes that comprise the Model, View, and ViewModel layers of my WPF application:

我有以下包含 WPF 应用程序的 Model、View 和 ViewModel 层的类:

  • App class (.xaml and .xaml.cs)
  • MainWindow class (.xaml and .xaml.cs)
  • MainWindowViewModel.cs
  • MalfunctionsView (.xaml and .cs)
  • MalfunctionsViewModel.cs
  • PartsView (.xaml and .cs)
  • PartsViewModel.cs
  • 应用程序类(.xaml 和 .xaml.cs)
  • MainWindow 类(.xaml 和 .xaml.cs)
  • 主窗口视图模型.cs
  • MalfunctionsView(.xaml 和 .cs)
  • 故障视图模型.cs
  • PartsView(.xaml 和 .cs)
  • 零件视图模型.cs

Basically I just have two views (Malfunctions and Parts) that get loaded up into the MainWindow view.

基本上我只有两个视图(故障和零件)加载到 MainWindow 视图中。

I have it setup right now so that I can comment code in and out to show either the MalfunctionView or the PartsView in the MainWindow. For example, if I want to see the MalfunctionView then I comment out all of the PartsView code and then re-run it in VS. Yes, I know... it's sad and pathetic, but I haven't learned how to unload one view and load another view on the fly. Which brings me to my question: how do I unload one view from the MainWindow and then load up a different view into the MainWindow?For example, I have a button on the PartsView called Select, which when clicked then needs to unload the PartsView from the MainWindow and load up the MalfunctionsView in it's place.

我现在已经设置好了,这样我就可以注释代码进出,以在 MainWindow 中显示 MalfunctionView 或 PartsView。例如,如果我想查看 MalfunctionView,那么我将所有 PartsView 代码注释掉,然后在 VS 中重新运行它。是的,我知道......这很可悲,但我还没有学会如何卸载一个视图并动态加载另一个视图。这让我想到了我的问题:如何从 MainWindow 卸载一个视图,然后将另一个视图加载到 MainWindow 中?例如,我在 PartsView 上有一个名为 Select 的按钮,单击该按钮后需要从 MainWindow 卸载 PartsView 并在其位置加载 MalfunctionsView。

I am including the code that I have for the App class and MainWindow View and MainWindow ViewModel so that it can be seen how I am currently loading up ViewModels (user controls) into the MainWindow.

我包含了 App 类和 MainWindow View 以及 MainWindow ViewModel 的代码,以便可以看到我当前如何将 ViewModel(用户控件)加载到 MainWindow 中。

App.xaml.cs

应用程序.xaml.cs

public partial class App : Application {
        protected override void OnStartup(StartupEventArgs e) {
            base.OnStartup(e);

            // Create MainWindow ViewModel
            var mainWindowVM = new MainWindowVM();

            // Create MainWindow View
            MainWindow mainWindowVw = new MainWindow();

            // Set MainWindow View datacontext to MainWindow ViewModel and then show the window
            mainWindowVw.DataContext = mainWindowVM;
            mainWindowVw.Show();   
        }
    }

MainWindow.xaml

主窗口.xaml

<Window x:Class="PAM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:PAM.ViewModel"
        xmlns:vw="clr-namespace:PAM.View"
        Title="Parts and Malfunctions" Height="800" Width="550">

    <Window.Resources>
        <DataTemplate DataType="{x:Type vm:MalfunctionsViewModel}">
            <vw:MalfunctionsView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:PartsViewModel}">
            <vw:PartsView />
        </DataTemplate>
    </Window.Resources>

    <Grid Width="Auto" Height="Auto">
        <ScrollViewer>
            <ItemsControl Width="Auto" Height="Auto" ItemsSource="{Binding ViewModels}"></ItemsControl>
        </ScrollViewer>
    </Grid>
</Window>

MainWindowViewModel.cs

主窗口视图模型.cs

public class MainWindowViewModel : ViewModelBase {

        readonly MalfunctionRepository _mfRepo;
        //readonly PartsRepository _pRepo;

        ObservableCollection<ViewModelBase> _viewModels;

        public ObservableCollection<ViewModelBase> ViewModels {
            get {
                if (_viewModels == null)
                    _viewModels = new ObservableCollection<ViewModelBase>();

                return _viewModels;
            }
        }

        public MainWindowViewModel() {

            // ================================
            // Malfunctions ViewModel
            _mfRepo = new MalfunctionRepository();

            MalfunctionsViewModel viewModel = new MalfunctionsViewModel(_mfRepo);

            // ================================
            // Parts ViewModel
            //_pRepo = new PartsRepository();

            //PartsViewModel viewModel = new PartsViewModel(_pRepo);

            this.ViewModels.Add(viewModel);
        }
    }

回答by Dean Kuga

In your MainWindow.xaml:

在您的 MainWindow.xaml 中:

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

In your ViewModel:

在您的视图模型中:

private object content;
public object Content
{
    get { return content; }
    set
{
    content = value; 
    NotifyPropertyChanged(p => p.Content);
}       

...

MalfunctionsViewModel mvm = new MalfunctionsViewModel(_mfRepo);
Content = mvm;

...

PartsViewModel pvm = new PartsViewModel(_pRepo);
Content = pvm;

Check out the very similar question I asked a few years back: WPF MVVM: How to load views "on demand" without using plug-in architecture?

查看我几年前问过的非常相似的问题:WPF MVVM:如何在不使用插件架构的情况下“按需”加载视图?