Caliburn.Micro框架学习笔记——多页面处理案例

作者 : admin 本文共2838个字,预计阅读时间需要8分钟 发布时间: 2024-06-2 共2人阅读

在聊这个之前,我们先来看一个静态类

在 Caliburn.Micro 中,ViewLocator 是一个用于查找和关联视图与视图模型的静态类。默认情况下,它根据约定(命名约定或其他规则)自动找到与视图模型相对应的视图。然而,有时我们需要自定义这一过程,以便在某些特殊情况下控制视图的定位和创建。

通过设置 ViewLocator.LocateForModelType,你可以提供一个自定义的逻辑来查找和创建视图。

Caliburn.Micro框架学习笔记——多页面处理案例插图

这里就是传入一个委托,这个委托是我们自定义的一个逻辑,它用于将视图模型类型映射到对应的视图。通过设置这个委托,你可以覆盖默认的视图定位逻辑。

基本结构——

public static Func LocateForModelType;

  • Type:视图模型的类型。
  • DependencyObject:上下文对象,通常是当前的视图。
  • object:上下文数据,通常是视图模型。
  • UIElement:返回找到的视图

 使用实例——

View层


    
        
    

VM层

namespace YourNamespace
{
    public class YourSpecialViewModel : Screen
    {
        // ViewModel logic for the special view
    }
}

在startup中创建他们的映射

 protected override void Configure()
        {
            // 设置自定义的视图定位器
            ViewLocator.LocateForModelType = new Func(OnLocateForModelType);
        }

        private UIElement OnLocateForModelType(Type modelType, DependencyObject displayLocation, object context)
        {
            // 自定义逻辑,例如根据某些条件选择视图
            if (modelType == typeof(YourSpecialViewModel))
            {
                return new YourSpecialView();
            }
            else
            {
                // 使用默认逻辑
                return ViewLocator.LocateForModelTypeDefault(modelType, displayLocation, context);
            }
        }

以上清楚之后,我们继续。

假设我们有多个窗口(UserControl),且要让他们显示在一个Tab中。那我们可以这么做。

首先先创建一个IChileViewModel这个来统一要显示的那几个usercontrol的VM,之后通过名称来进行判别打开的要是哪个。

   public interface IChildViewModel
   {
   }

然后在一开始的时候,我们讲过ViewLocator这个内容,这个很重要,我们可以自定义一个匹配逻辑如下——

private UIElement OnLocateForModelType(Type type, DependencyObject d, object obj)
{
  
    string name = type.FullName;

    name = name.Replace(".ViewModels.", ".Views.");
    if (name.EndsWith("Model"))
        name = name.Substring(0, name.Length - 5);

    var t = Assembly.GetExecutingAssembly().GetType(name);
    //这里可以顺便注入view

    return (UIElement)Activator.CreateInstance(t);
}

于是在startup这个类中,初始类配置代码为——》

  internal class Startup : BootstrapperBase
  {
      private SimpleContainer _container;

      public Startup()
      {
          this.Initialize();

          ViewLocator.LocateForModelType =
              new Func(OnLocateForModelType);
      }
      private UIElement OnLocateForModelType(Type type, DependencyObject d, object obj)
      {
        
          string name = type.FullName;

          name = name.Replace(".ViewModels.", ".Views.");
          if (name.EndsWith("Model"))
              name = name.Substring(0, name.Length - 5);

          var t = Assembly.GetExecutingAssembly().GetType(name);
          // 这里可以加入View的依赖注入功能

          //----------------------------------

          return (UIElement)Activator.CreateInstance(t);
      }

      protected override async void OnStartup(object sender, StartupEventArgs e)
      {
          await DisplayRootViewForAsync();
      }

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

          this._container
              .Singleton()
              .Singleton();

          this._container
              .PerRequest()
              .Singleton("A")
              .Singleton("B")
              .Singleton("C");

      }

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

 这里注入时,通过特定字母进行之后的窗体索引。

于是在Mainview中可以创建如下,用来做测试

Caliburn.Micro框架学习笔记——多页面处理案例插图(1)

VM中的逻辑为

  // 使用TabControl -》必须 Conductor.Collection
  public class MainViewModel : Conductor.Collection.OneActive
  {
      public async void ShowPage(string name)
      {
          var vm = IoC.Get(name);
          await this.ActivateItemAsync(vm);
      }
  }

这里需要注意的是,要显示的那几个内容,都需要继承IChlidViewModel和Screen。然后通过MainView做统一管理,所以其需要继承Conductor。

当我按下其中一个按钮,要将其显示在tabcontrl中时,此时会跳转到之前的ViewLocator中去进行映射。而映射的根据就是我按钮按下传入的参数。

这样就可以做到一个页面显示tab。

 

本站无任何商业行为
个人在线分享 » Caliburn.Micro框架学习笔记——多页面处理案例
E-->