WPF随笔(十三)--MVVM模式下的窗口管理

使用MVVM模式的WPF项目和传统的使用事件驱动模式的WPF在处理逻辑有所不同,即使最简单的打开窗口也有很大差异。


1.创建窗口管理类

    public static class WindowManager
    {
        private static Hashtable _RegisterWindow = new Hashtable();

		//注册窗口
        public static void Regiter<T>(string key)
        {
            _RegisterWindow.Add(key, typeof(T));
        }

		//注册窗口
        public static void Regiter(string key, Type t)
        {
            if (!_RegisterWindow.ContainsKey(key))
                _RegisterWindow.Add(key, t);
        }

		//移除窗口
        public static void Remove(string key)
        {
            if (_RegisterWindow.ContainsKey(key))
                _RegisterWindow.Remove(key);
        }

		//打开窗口
        public static void ShowDialog(string key, object VM)
        {
            if (!_RegisterWindow.ContainsKey(key))
            {
                throw (new Exception("没有注册此键!"));
            }

            var win = (Window)Activator.CreateInstance((Type)_RegisterWindow[key]);
            win.DataContext = VM;
            win.ShowDialog();
        }

		//打开窗口
        public static void ShowDialog(string key, object model,Window window)
        {
            if (!_RegisterWindow.ContainsKey(key))
            {
                throw (new Exception("没有注册此键!"));
            }

            var win = (Window)Activator.CreateInstance((Type)_RegisterWindow[key]);
            win.DataContext = model;
            win.Owner = window;
            win.ShowDialog();
        }

    }

2.添加窗口类扩展

    public static class WindowExtension
    {
        public static void Register(this Window win, string key)
        {
            WindowManager.Regiter(key, win.GetType());
        }

        public static void Register(this Window win, string key, Type t)
        {
            WindowManager.Regiter(key, t);
        }

        public static void Register<T>(this Window win, string key)
        {
            WindowManager.Regiter<T>(key);
        }
    }

3.创建ViewModel层基类

在ViewModel层的基类ViewModelBase中,除了定义打开Window窗口的方法外,还有MessageBox消息弹出框、文件选择对话框和文件夹选择对话框。

    public class ViewModelBase : INotifyPropertyChanged
    {
        #region Window-窗口管理
        //打开窗口
        public void ShowDialog(string key, object vm)
        {
            WindowManager.ShowDialog(key, vm);
        }

        //打开窗口并设置所属窗口
        public void ShowDialog(string key,object args,Window owner)
        {
            WindowManager.ShowDialog(key, args, owner);
        }

        //消息提示框
        public void ShowMessage(string mes, string title = "", MessageBoxButton buttons = MessageBoxButton.OK)
        {
            MessageBox.Show(mes, title, buttons);
        }

        //带返回结果的消息提示框
        public bool ShowMessageWithResult(string content,string title="",MessageBoxButton button=MessageBoxButton.OKCancel)
        {
            if (MessageBox.Show(content, title,button)==MessageBoxResult.OK)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        //文件选择对话框
        public string ShowFileDialog(string title,string filter="docx|*.docx",string folder= "C:\\Users\\Administrator\\Desktop")
        {
            string filePath = "";
            SaveFileDialog dialog = new SaveFileDialog();
            dialog.Title = title;
            dialog.Filter = filter;
            dialog.InitialDirectory = folder;
            if (dialog.ShowDialog()==true)
            {
                filePath = dialog.FileName;
            }
            return filePath;

        }

        //文件夹选择对话框
        public string ShowFolderDialog(string title)
        {
            string folderPath = "";
            System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
            dialog.RootFolder = Environment.SpecialFolder.MyDocuments;
            dialog.ShowNewFolderButton = true;
            dialog.Description = title;
            if (dialog.ShowDialog()==System.Windows.Forms.DialogResult.OK) 
            {
                folderPath = dialog.SelectedPath;
            };
            
            return folderPath;
        }

        #endregion

        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        protected internal virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }

注意:示例采用是,NET Core 3.1开发环境,文件选择对话框SaveFileDialog 需要引用Microsoft.Win32,文件夹选择对话框FolderBrowserDialog需要手动引用C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.1目录下的System.Windows.Forms.dll

4.窗口注册

在主窗口类MainWindow.xaml.cs中通过名称注册新的窗口。

    public partial class MainWindow : MetroWindow, ISingletonDependency

    {
        private MainWindowViewModel _viewModel;
        public static MetroWindow Instance
        {
            get; private set;
        }

        public MainWindow()
        {
            _viewModel = new MainWindowViewModel();
            this.DataContext = _viewModel;
            InitializeComponent();
            this.Register<DemoView>("DemoView");//注册窗口
            Instance = this;
        }
    }

5.窗口使用

在ViewModel层的类中,由于已经继承了基类ViewModelBase,窗口管理相关的类都可以直接使用。

    public class MainWindowViewModel : ViewModelBase
    {
        public MainWindowViewModel()
        {
            OpenDemoCommand = new DelegateCommands<string>(OpenDemoWindow);
        }

        #region Commands

        public DelegateCommands<string> OpenDemoCommand { get; set; }

        #endregion

        #region Methods

        #region 打开窗口示例
        private void OpenDemoWindow(string obj)
        {
            DemoViewModel viewModel = new DemoViewModel ();
            ShowDialog("DemoView", viewModel, MainWindow.Instance);
        }
        #endregion


        #endregion


    }

你可能感兴趣的:(WPF)