WPF-MVVM子窗体及主窗体的切换(全局ViewModel)

背景说明

在项目开发过程过程中,常常会遇到单个窗体作为容器,但是需要多个界面之间的跳转问题,此时,则需要公用ViewModel,尤其是在跳转的子界面。

案例说明

当前案例是将需要跳转窗体的ViewModel作为全局的集合,在ViewModel内进行实例化,同时,在跳转的子窗体也是绑定这个静态的全局ViewModel,这样就可以将子窗体的委托事件作为公共化,可以提供在其他的窗体进行订阅,实现1号窗体的方法可以触发2号窗体的功能。

代码如下

MyCommand代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace GlobalMVVM
{
    public class MyCommand:ICommand
    {
        private readonly Action _execute;
        private readonly Func<bool> _canExecute;

        private readonly Action<object> _execute2;


        public MyCommand(Action execute, Func<bool> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute == null || _canExecute();
        }

        public void Execute(object parameter)
        {
            _execute();
    
        }



    }
}

Notify

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace GlobalMVVM
{
    public abstract class Notify : INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged([CallerMemberName] string name = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

    }
}

CTQHMainView.xaml

<Window x:Class="GlobalMVVM.View.CTQHMainView"
        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:GlobalMVVM.View"
        mc:Ignorable="d"
        Title="CTQHMainView" Height="450" Width="800">
    <Grid>
        <ContentControl Margin="0,0,5,0"  Background="Transparent"   Content="{Binding CurrentViewModel}"  BorderThickness="0"/>
    </Grid>
</Window>

CTQHMainView.cs

using GlobalMVVM.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace GlobalMVVM.View
{
    /// <summary>
    /// CTQHMainView.xaml 的交互逻辑
    /// </summary>
    public partial class CTQHMainView : Window
    {
        public CTQHMainView()
        {
            InitializeComponent();
            this.DataContext = new CTQHMainViewModel();
        }
    }
}

Page1View.xaml

<Page x:Class="GlobalMVVM.View.Page1View"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:GlobalMVVM.View"
      mc:Ignorable="d" 
      d:DesignHeight="450" d:DesignWidth="800"
      Title="Page1View">

    <Grid>
        <Button Content="进入界面2" HorizontalAlignment="Left" VerticalAlignment="Top"  Command="{Binding CQTHCommand2}" Margin="365,236,0,0"/>

    </Grid>
</Page>

Page1View.cs

using GlobalMVVM.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace GlobalMVVM.View
{
    /// <summary>
    /// Page1View.xaml 的交互逻辑
    /// </summary>
    public partial class Page1View : Page
    {
        public Page1View()
        {
            InitializeComponent();
            this.DataContext = CTQHMainViewModel.page1Model1;
        }
    }
}

Page2View.xaml

<Page x:Class="GlobalMVVM.View.Page2View"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:GlobalMVVM.View"
      mc:Ignorable="d" 
      d:DesignHeight="450" d:DesignWidth="800"
      Title="Page2View">

    <Grid>

        <Grid>

            <Grid.RowDefinitions>
                <RowDefinition Height="50"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Border Grid.Row="0" Background="Blue"/>
            <Grid Grid.Row="1">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Border Grid.Column="0" Background="Crimson"/>
                <Border Grid.Column="1" Background="Red"/>
            </Grid>
        </Grid>
        <Button Content="返回界面1" HorizontalAlignment="Left" VerticalAlignment="Top"  Command="{Binding CQTHCommand1}" Margin="726,21,0,0"/>

    </Grid>
</Page>

Page2View.cs

using GlobalMVVM.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace GlobalMVVM.View
{
    /// <summary>
    /// Page2View.xaml 的交互逻辑
    /// </summary>
    public partial class Page2View : Page
    {
        public Page2View()
        {
            InitializeComponent();
            this.DataContext = CTQHMainViewModel.page1Model2;

        }
    }
}

CTQHMainViewModel

using GlobalMVVM.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace GlobalMVVM.ViewModel
{
    public class CTQHMainViewModel : Notify
    {
        public MyCommand CQTHCommand1 { set; get; }
        public MyCommand CQTHCommand2 { set; get; }

        private Page1View page1 = new Page1View();
        private Page2View page2 = new Page2View();

        public static Page1ViewModel page1Model1 = new Page1ViewModel();
        public static Page2ViewModel page1Model2 = new Page2ViewModel();

        public CTQHMainViewModel()
        {

            CQTHCommand1 = new MyCommand(ShowPage1);
            ShowPage1();
            page1Model1.MethodExecuted += MyUserControl_MyButtonClicked;
            page1Model2.MethodExecuted += MyUserControl_MyButtonClicked2;
        }


        private Frame currenrframe;
        public Frame CurrentViewModel
        {
            get { return currenrframe; }
            set
            {
                currenrframe = value;
                OnPropertyChanged();
            }
        }


        public void ShowPage1()
        {
            Page frm = (Page)page1;
            Frame frame = new Frame();
            frame.Content = frm;
            CurrentViewModel = frame;
        }


        private void MyUserControl_MyButtonClicked(object sender, System.EventArgs e)
        {
            Page frm = (Page)page2;
            Frame frame = new Frame();
            frame.Content = frm;
            CurrentViewModel = frame;
        }

        private void MyUserControl_MyButtonClicked2(object sender, System.EventArgs e)
        {
            Page frm = (Page)page1;
            Frame frame = new Frame();
            frame.Content = frm;
            CurrentViewModel = frame;
        }
    }
}

Page1ViewModel

using GlobalMVVM.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace GlobalMVVM.ViewModel
{
    public class Page1ViewModel : Notify
    {

        public event EventHandler MethodExecuted;



        public static MyCommand CQTHCommand2 { set; get; }

        private Page2View page2 = new Page2View();

        public Page1ViewModel()
        {
            CQTHCommand2 = new MyCommand(ShowPage2);
        }



        private Frame currenrframe;
        public Frame CurrentViewModel
        {
            get { return currenrframe; }
            set
            {
                currenrframe = value;
                OnPropertyChanged();
            }
        }


        public void ShowPage2()
        {
            // 触发事件
            MethodExecuted?.Invoke(this, EventArgs.Empty);
        }



    }
}


Page2ViewModel

using GlobalMVVM.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace GlobalMVVM.ViewModel
{

    public class Page2ViewModel : Notify
    {
        public event EventHandler MethodExecuted;



        public static MyCommand CQTHCommand1 { set; get; }

        private Page1View page2 = new Page1View();

        public Page2ViewModel()
        {
            CQTHCommand1 = new MyCommand(ShowPage1);
        }



        private Frame currenrframe;
        public Frame CurrentViewModel
        {
            get { return currenrframe; }
            set
            {
                currenrframe = value;
                OnPropertyChanged();
            }
        }


        public void ShowPage1()
        {
            // 触发事件
            MethodExecuted?.Invoke(this, EventArgs.Empty);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值