Caliburn.Micro框架学习笔记——窗体管理对象的基本使用

Caliburn.Micro 的窗口管理器(Window Manager)是一个强大的工具,用于管理 WPF 应用程序中的窗口和对话框。它简化了窗口的创建、显示和关闭等操作,使得视图和视图模型的交互更加直观和易于维护。

它能够实现的功能包括

  1. 显示窗口

    • 打开一个新的窗口,并将指定的视图模型作为其数据上下文。
  2. 显示对话框

    • 打开一个模式对话框,并将指定的视图模型作为其数据上下文。
  3. 显示弹出窗口

    • 显示一个非模态弹出窗口,通常用于消息通知或临时窗口。

使用步骤

配置窗口管理器

AppBootstrapper 中注册 IWindowManager

 internal class Startup : BootstrapperBase
 {
     private SimpleContainer _container;

     public Startup()
     {
         this.Initialize();
     }
     protected override async void OnStartup(object sender, StartupEventArgs e)
     {
         IDictionary<string, object> args = new Dictionary<string, object>();
         args.Add("Width", 500);
         args.Add("Height", 300);
         args.Add("Foreground", Brushes.Red);
         await DisplayRootViewForAsync<MainViewModel>(args);//窗口初始化样式
     }

     protected override void Configure()
     {
         _container = new SimpleContainer();
         this._container.Instance(this._container);

         this._container
             .Singleton<IEventAggregator, EventAggregator>()//注入事件管理器
             .Singleton<IWindowManager, MyWindowManager>();//注入窗口管理器

         this._container
             .PerRequest<MainViewModel>()//程序中相应的窗口对应的ViewModel
             .PerRequest<AViewModel>()
             .PerRequest<BViewModel>();
     }

     protected override object GetInstance(Type service, string key)
     {
         return this._container.GetInstance(service, key);
     }

 其中MyWindowManager为继承了WindowManager的自定义重写后的窗体管理器。

 internal class MyWindowManager : WindowManager
 {
     protected override Window EnsureWindow(object model, object view, bool isDialog)
     {
         Window win = base.EnsureWindow(model, view, isDialog);

         WindowChrome windowChrome = new WindowChrome();
         windowChrome.NonClientFrameEdges = NonClientFrameEdges.None;
         // 这里是设置窗口边框厚度(-1 Win11   0  1   Win10)
         windowChrome.GlassFrameThickness = new Thickness(-1);
         windowChrome.UseAeroCaptionButtons = false;
         WindowChrome.SetWindowChrome(win, windowChrome);

         return win;
     }
 }

使用窗口管理器显示窗口或对话框

在视图模型中通过依赖注入获取 IWindowManager 并使用它显示窗口或对话框。这里就是当我们要在哪里打开哪个窗口时,就在哪里进行依赖注入去使用它。

using Caliburn.Micro;

public class ShellViewModel : Screen
{
    private readonly IWindowManager _windowManager;

    public ShellViewModel(IWindowManager windowManager)
    {
        _windowManager = windowManager;
    }

    public void ShowAnotherWindow()//打开一个一般窗口
    {
        var anotherViewModel = new AnotherViewModel();
        _windowManager.ShowWindow(anotherViewModel);
    }

    public void ShowDialog()//打开模态窗口
    {
        var anotherViewModel = new AnotherViewModel();
        _windowManager.ShowDialog(anotherViewModel);
    }

    public void ShowPopup()//类似于泡泡弹窗
    {
        var anotherViewModel = new AnotherViewModel();
        _windowManager.ShowPopup(anotherViewModel);
    }
}

 当然也可以有如下使用异步的方法来操作

public async void OpenWindow()
{
    // 触发打开另一个窗口
    // 打开一个模态窗口:AView
    // 传参
    string arg = "Hello";

    var vm = IoC.Get<AViewModel>();
    vm.Title = arg;

    //IDictionary<string, object> args = new Dictionary<string, object>();
    //args.Add("Width", 300);
    //args.Add("Height", 200);
    //args.Add("Foreground", Brushes.Red);

    //WindowChrome windowChrome = new WindowChrome();
    //windowChrome.NonClientFrameEdges = NonClientFrameEdges.None;
    //windowChrome.GlassFrameThickness = new Thickness(0);
    //windowChrome.UseAeroCaptionButtons = false;
    //args.Add("WindowChrome.WindowChrome", windowChrome);

    //var result = await windowManager.ShowDialogAsync(vm, settings: args);
    var result = await windowManager.ShowDialogAsync(vm);
    if (result == true)
    {
        // 处理vm 中的数据
        this.Value = vm.Value;
    }


    // 打开一个一般的窗口
    //await windowManager.ShowWindowAsync(vm);


}

public async void OpenPopup()
{
    // 打开一个Popup 
    // Popup内容的数据源
    var vm = IoC.Get<BViewModel>();
    // 这里如果遇到未实例化的异常,首先考虑未注册
    await windowManager.ShowPopupAsync(vm);
}

视图模型基类Screen

Screen 对象是视图模型的基类,提供了生命周期管理和一些辅助功能。通过继承 Screen 类,视图模型可以自动获得生命周期事件的支持,这些事件可以用于管理资源、更新 UI 或执行其他操作

Screen 对象通常用作视图模型的基类,提供以下主要功能:

  • 生命周期管理:通过 OnActivateOnDeactivate 方法管理视图模型的激活和停用。
  • 属性更改通知:通过实现 INotifyPropertyChanged 接口来通知 UI 更新。
  • 协作与导航:通过与 Conductor 对象一起工作,管理复杂的导航和视图模型间的交互
protected override void OnActivate()
    {
        base.OnActivate();
        // Code to run when the view model is activated
    }

    protected override void OnDeactivate(bool close)
    {
        base.OnDeactivate(close);
        // Code to run when the view model is deactivated
        if (close)
        {
            // Cleanup code if the view model is permanently closed
        }
    }

    public void Save()
    {
        // Save logic
    }

 视图管理基类Conduct<T>

Conductor 是一个负责管理其他视图模型的类。它是一个高级的视图模型,提供了一种机制来协调多个子视图模型的生命周期和显示。Conductor 可以管理单个活动项(一个视图模型)或多个活动项(多个视图模型),根据需要动态地激活或停用这些视图模型。

Conductor 的主要类型

  1. Conductor<T>:管理单个活动项。
  2. Conductor<T>.Collection.OneActive:管理一个活动项集合,其中只有一个项可以处于激活状态。
  3. Conductor<T>.Collection.AllActive:管理一个活动项集合,其中所有项都可以处于激活状态。

主要功能

  • 激活和停用:管理子视图模型的激活和停用。
  • 生命周期管理:协调子视图模型的生命周期事件。
  • 导航:在不同视图模型之间导航。
  • 集合管理:管理多个子视图模型的集合。
  • Conductor 类的主要方法
  • ActivateItem:激活指定的子项。
  • DeactivateItem:停用指定的子项。
  • CloseItem:关闭指定的子项。
  • OnActivate:当 Conductor 被激活时调用。
  • OnDeactivate:当 Conductor 被停用时调用。

 管理单个活动项

public class ShellViewModel : Conductor<object>
{
    private readonly SimpleContainer _container;

    public ShellViewModel(SimpleContainer container)
    {
        _container = container;
    }

    public void ShowFirstView()
    {
        var firstViewModel = _container.GetInstance<FirstViewModel>();
        ActivateItem(firstViewModel);
    }

    public void ShowSecondView()
    {
        var secondViewModel = _container.GetInstance<SecondViewModel>();
        ActivateItem(secondViewModel);
    }

    protected override void OnActivate()
    {
        base.OnActivate();
        ShowFirstView(); // 默认显示第一个视图
    }
}

其中First和Second的视图均继承自Screen。

管理多个活动项(一个活动)

public class ShellViewModel : Conductor<IScreen>.Collection.OneActive
{
    private readonly SimpleContainer _container;

    public ShellViewModel(SimpleContainer container)
    {
        _container = container;

        Items.Add(_container.GetInstance<FirstViewModel>());
        Items.Add(_container.GetInstance<SecondViewModel>());
    }

    protected override void OnActivate()
    {
        base.OnActivate();
        ActivateItem(Items[0]); // 默认激活第一个视图
    }
}

总结

  • Conductor<T>:管理单个活动项,适用于需要在不同视图模型之间进行单一激活的场景。
  • Conductor<T>.Collection.OneActive:管理一个活动项集合,其中只有一个项可以处于激活状态,适用于需要在多个视图模型之间进行单一激活的场景。
  • Conductor<T>.Collection.AllActive:管理一个活动项集合,其中所有项都可以处于激活状态,适用于需要多个视图模型同时激活的场景。

通过使用 Conductor 类,Caliburn.Micro 提供了一种强大而灵活的方式来管理和协调视图模型的生命周期和导航。这使得开发复杂的、多视图模型的应用程序变得更加容易和高效

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-06 22:20:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-06 22:20:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-06 22:20:03       82 阅读
  4. Python语言-面向对象

    2024-06-06 22:20:03       91 阅读

热门阅读

  1. 深度学习之动量momentum介绍

    2024-06-06 22:20:03       27 阅读
  2. 力扣每日一题 6/6

    2024-06-06 22:20:03       35 阅读
  3. Springboot+WebSocket实现消息推送

    2024-06-06 22:20:03       26 阅读
  4. 嵌入式学习——网络编程(UDP)——day30

    2024-06-06 22:20:03       28 阅读
  5. iPhone 语言编程:深入探索与无限可能

    2024-06-06 22:20:03       32 阅读