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


    }
  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
WPF MVVM模式下,窗口的ShowDialog实现是通过使用自定义的对话框服务来实现的。 首先,我们需要创建一个实现了IDialogService接口的自定义对话框服务类,该接口定义了ShowDialog方法。例如: ``` public interface IDialogService { bool? ShowDialog(object viewModel); } ``` 然后,在实际的对话框服务类中,我们可以使用WPFWindow或者其他自定义的Window来实现ShowDialog方法。在ShowDialog方法内部,我们可以根据传入的ViewModel来创建对应的视图,并将ViewModel与视图进行关联。例如: ``` public class DialogService : IDialogService { public bool? ShowDialog(object viewModel) { var dialogWindow = new DialogWindow(); dialogWindow.DataContext = viewModel; return dialogWindow.ShowDialog(); } } ``` 在ViewModel中,我们需要使用对话框服务来调用ShowDialog方法,并将当前的视图模型作为参数传入。在调用ShowDialog方法后,可以根据返回值来判断对话框是通过"确定"按钮还是"取消"按钮关闭的。例如: ``` public class MainViewModel { private readonly IDialogService _dialogService; public MainViewModel(IDialogService dialogService) { _dialogService = dialogService; } public void OpenDialog() { var dialogViewModel = new DialogViewModel(); var result = _dialogService.ShowDialog(dialogViewModel); if (result == true) { // 确定按钮被点击 } else if (result == false) { // 取消按钮被点击 } } } ``` 最后,在使用MVVM模式的主视图或者其他视图中,我们可以通过依赖注入或者其他方式来创建对话框服务的实例,并将其作为参数传入ViewModel的构造函数中,以便于在ViewModel中调用ShowDialog方法来展示对话框。例如: ``` public partial class MainWindow : Window { private readonly MainViewModel _viewModel; public MainWindow() { InitializeComponent(); var dialogService = new DialogService(); _viewModel = new MainViewModel(dialogService); DataContext = _viewModel; } private void OpenDialogButton_Click(object sender, RoutedEventArgs e) { _viewModel.OpenDialog(); } } ``` 通过以上步骤,我们就可以实现在WPF MVVM模式窗口ShowDialog的功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值