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

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

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

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

ce02adecaaf1447599b48e8c855c9d13.png

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

基本结构——

public static Func<Type, DependencyObject, object, UIElement> LocateForModelType;

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

 使用实例——

View层

<Window x:Class="YourNamespace.YourSpecialView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="YourSpecialView" Height="200" Width="300">
    <Grid>
        <TextBlock Text="This is a special view!" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Window>

VM层

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

在startup中创建他们的映射

 protected override void Configure()
        {
            // 设置自定义的视图定位器
            ViewLocator.LocateForModelType = new Func<Type, DependencyObject, object, UIElement>(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<Type, DependencyObject, object, UIElement>(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<MainViewModel>();
      }

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

          this._container
              .Singleton<IEventAggregator, EventAggregator>()
              .Singleton<IWindowManager, WindowManager>();

          this._container
              .PerRequest<MainViewModel>()
              .Singleton<IChildViewModel, AViewModel>("A")
              .Singleton<IChildViewModel, BViewModel>("B")
              .Singleton<IChildViewModel, CViewModel>("C");

      }

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

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

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

cdfd12d72d3640a79ddb77a47d61d665.png

VM中的逻辑为

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

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

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

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

 

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
WPF(Windows Presentation Foundation)是一种用于创建Windows桌面应用程序的用户界面框架,而Caliburn.Micro是一种针对WPF应用程序的轻量级MVVM框架。通过结合使用这两个框架,可以更高效地编写WPF应用程序的界面和逻辑部分。 一个基本的WPF Caliburn.Micro框架编写案例可以是一个简单的待办事项列表应用程序。首先,我们可以创建一个WPF应用程序,并添加Caliburn.Micro框架的引用。然后,我们可以定义待办事项的模型,包括待办事项的名称、描述和状态等属性。 接下来,我们可以使用Caliburn.Micro框架提供的ViewModelBase类来创建一个待办事项的视图模型。在视图模型中,我们可以定义与界面交互的属性和命令,比如显示待办事项列表、添加新的待办事项、标记已完成的待办事项等功能。 然后,我们需要创建一个WPF的视图,用于显示待办事项列表和与用户进行交互。在视图中,我们可以绑定视图模型中的属性和命令,并使用WPF的控件来显示和编辑待办事项。 最后,我们将视图模型绑定到视图上,使得视图与视图模型能够实现双向的数据绑定和命令绑定。这样,当用户在界面上进行操作时,视图和视图模型之间的数据和行为可以实现同步。 通过这样一个简单的案例,我们可以看到WPF Caliburn.Micro框架编写的优势,它能够帮助我们更快速和高效地构建WPF应用程序,并实现良好的界面和逻辑分离。同时,借助MVVM架构,我们也能够实现更好的代码可读性和可维护性。 WPF Caliburn.Micro框架编写案例的实践将有助于我们更好地理解和运用这些框架,提升WPF应用程序的开发效率和质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Matrix Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值