开源项目地址:https://gitee.com/easyxaf/blazor-tabbed-mdi

前言

XAF在WinForm中采用了多文档界面(MDI),但在Blazor中却没有,在官网中也有人提相关的问题,官方的回复是将来会考虑实现MDI(等待的时间可能会很长),同时官方也给了一些临时方案,如借用浏览器的Tab或用DashboardView来实现,其实这些方案都存在着一些问题。之前在QQ群(336090194)中上传了一个简单的MDI实现(MdiBlazorSample_20220726.zip),它是通过创建一个WindowTemplate,重写IFrameTemplate的SetView方法来实现的。新的MDI也采用了类似的方法,但加入了更多的功能,事后我会写一篇关于MDI的实现原理,感兴趣的可以关注一下。

XAF中的Blazor提供的是一个单文档界面(SDI),当我们切换视图时,上一个视图的状态会丢失,比如在一个列表视图中查看详情,当再返回列表视图时,列表视图中的过滤、翻页等状态都会丢失,这样用户体验不是很好。MDI可以很好的解决这个问题,由于它可以同时保留多个视图的状态,这样再切换视图时,视图之前的状态不会丢失。

在XAF中我们更多的是对视图进行操作,但视图是被Window(或Frame)包裹的,在BlazorTabbedMdi中每一个视图都有一个Window,其实都是对Window进行操作,为了便于理解,将其描述为视图。

演示

基本操作

未保存提示

  • 如果视图被修改了,会在标题的后面加上*,保存后*会被移除
  • 试图关闭未保存的视图时,会给出提示
  • 关闭浏览器时,如果有未保存的视图,也会给出提示

导航历史

  • 在切换视图时,地址栏、导航栏、Tab页会同步显示对应的视图
  • 通过操作浏览器中的历史(前进、后退),可以对视图进行切换

Tab右键菜单

  • 通过右键菜单可以快速的关闭Tab页
  • 可以将Tab页移动到新的浏览器窗口

窗口管理

  • 窗口列表中包含了所有已被打开的视图
  • 可以激活、批量保存、批量关闭

Tab分组

  • 当打开的视图过多时,通过分组,可以更方便的操作视图
  • 分组规则可以在模型中设置,默认分组规则是将相同BO类型放在一组
  • 当切换视图时,同时也会显示它所在的组
  • 所有已打开的视图,都可以在窗口管理中查看到

无Tab页

  • 不显示Tab页,但保留了视图的状态
  • 可以通过导航栏或窗口管理对视图进行切换

使用

基本

  1. 将BlazorTabbedMdi项目引入到解决方案中

  2. 在Startup类中将BlazorTabbedMdiModule模块添加到配置中

  3. 将Blazor项目中Application的基类(之前是BlazorApplication)改为MdiBlazorApplication

完成上面的步骤后,就可直接使用了,如果想使用分组或无Tab页需要在模型中设置,打开模型编辑器,在Application节点中找到Mdi节点组

  • IsWindowKeepOpen:当为True时,保持视图的状态,默认为True
  • IsShowTabbedMdi:当为True时,显示Tab页(即使IsWindowKeepOpen为False,也会保持视图状态),默认为True
  • EnableMdiGroup:当为True时,启用分组(需要IsShowTabbedMdi为True),默认为False

默认分组规则是相同BO类型会放在一组,如果想修改默认规则需要在模块中设置,每一个视图都可以单独的设置,MdiGroup默认为空,组名称相同的会放到同一组中

高级

BlazorTabbedMdi使用了自定义的WindowTemplate,如果你不想使用默认的模板样式,可以有两种方式:

一、直接在BlazorTabbedMdi项目中修改MdiMainWindowTemplateComponent.razor文件,这是比较简单的方式;

二、如果你想将BlazorTabbedMdi项目作为独立模块使用,不想直接修改,可以按照下面的步骤操作。

  1. 将MdiMainWindowTemplateComponent.razor与MdiMainWindowTemplateComponent.razor.cs文件拷贝到你的Blazor项目中,将其改名为CustomMainWindowTemplateComponent,修改并补全相应的命名空间。
  2. 在你的Blazor项目创建一个继承自MdiMainWindowTemplate的类(如:CustomMainWindowTemplate)
  3. CustomMainWindowTemplate.cs中的代码如下

  4. CustomMainWindowTemplateComponent.razor与CustomMainWindowTemplateComponent.razor.cs的基类需要改为FrameTemplateComponentBase<CustomMainWindowTemplate>



  5. 将CustomMainWindowTemplateComponent.razor中的Create代码替换为

  6. 在Blazor项目中的Application类里添加下面的代码

  7. 通过修改CustomMainWindowTemplateComponent文件就可以实现自定义布局及样式
  8. 这种方式比较繁琐(在示例文件中包含了全部代码),如果没有独立使用的必要可以直接使用第一种方法

XAF Blazor TabbedMdi的更多相关文章

  1. XAF新手入门 - 模块(Module)

    模块概述 谈到模块大家应该都不会感到陌生,不管是前端还是后端都有模块的概念,XAF中的模块概念与大多数框架中的模块概念是相通的.XAF模块首先是一个.NET类库,同时它还包含一个继承自ModuleBa ...

  2. XAF新手入门 - 前言

    很多小伙伴在第一次接触XAF时,会被它的丰富功能及开箱即用的特点所吸引,即使在不了解XAF的情况下,也能够依葫芦画瓢创建一个功能丰富的应用,但当应用到实际项目中时,你会发现与之前的愿景差距很大,很多都 ...

  3. XAF新手入门 - 类型子系统(Types Info Subsystem)

    类型子系统概述 类型子系统是XAF的核心概念,但我们平时却很少关注它,它集中存储了模块中的类型,它是生成应用程序模型(Application Model)的基础,它与XAF中其它的概念都有所关联,了解 ...

  4. 如何汉化XAF应用

    这是一个入门级的问题,应网友请求,总结一下XAF汉化过程的几个关键点. 一.所有Dev的控件的汉化,Dev官方有汉化文件.点击下载15.2版本. 正版用户登陆至官网是有专门的下载界面的,并且可以参与汉 ...

  5. XAF视频教程来啦,已出7课

        XAF交流学习群内的兄弟录制了视频,他没有博客,委拖我发至博客园,希望能让更多的开发人员受益.快速开发企业级应用的好工具!   XAF入门01快速浏览   XAF入门02特点. XAF入门03 ...

  6. XAF 如何基于业务规则禁用属性

    // Developer Express Code Central Example: // How to: Disable Property Editors Based on a Business R ...

  7. XAF 如何将数据库中Byte array图片显示出来

    问题比较简单,直接上代码. private Image _Cover; [Size(SizeAttribute.Unlimited), ValueConverter(typeof(ImageValue ...

  8. XAF视频教程来啦,已出15课

    第一到第七课在这里: http://www.cnblogs.com/foreachlife/p/xafvideo_1_6.html 视频地址:http://i.youku.com/i/UMTI5OTE ...

  9. XAF:如何让用户在运行时个性化界面并将个性化信息保存到数据库中 win/web/entityframework/xpo

    本主题介绍如何启用管理模型差异(XAFML),并将设置存储在数据库中.   名词解释: 1.模型:XAF中把所有应用程序的结构都用模型来定义,比如列表,有哪些列,名称是什么,对应的字段名是什么,业务对 ...

  10. XAF点滴:很具体很用实用---处理三个小问题

    以下内容全部为web版本的老模板风格下完成. 一.在编辑状态的详细视图下打印报表. 有些时候,需要在编辑状态下直接打印报表内容,官方默认是不允许这样做的.用Reflector查看源码,可以看到: De ...

随机推荐

  1. 使用 arxiv-sanity &paperwithcode 跟进最新研究领域的文章

    1.arxiv-sanity介绍 arxiv.org是一个非常大的预印本资源库,里面有大量的最新的论文,但缺点是浏览.搜索和排序不是很方便.这个资源库每天会更新大量的论文,如果通过手动搜索和浏览则效率 ...

  2. 4.8 C++ Boost 应用JSON解析库

    property_tree 是 Boost 库中的一个头文件库,用于处理和解析基于 XML.Json 或者 INFO 格式的数据. property_tree 可以提供一个轻量级的.灵活的.基于二叉数 ...

  3. C++ STL 标准模板库(容器总结)算法

    C++ 标准模板库STL,是一个使用模板技术实现的通用程序库,该库由容器container,算法algorithm,迭代器iterator,容器和算法之间通过迭代器进行无缝连接,其中所包含的数据结构都 ...

  4. LyScript 实现应用层钩子扫描器

    Capstone 是一个轻量级的多平台.多架构的反汇编框架,该模块支持目前所有通用操作系统,反汇编架构几乎全部支持,本篇文章将运用LyScript插件结合Capstone反汇编引擎实现一个钩子扫描器. ...

  5. Java多线程-ThreadLocal(六)

    为了提高CPU的利用率,工程师们创造了多线程.但是线程们说:要有光!(为了减少线程创建(T1启动)和销毁(T3切换)的时间),于是工程师们又接着创造了线程池ThreadPool.就这样就可以了吗?-- ...

  6. 论文精读:用于少样本图像识别的语义提示(Semantic Prompt for Few-Shot Image Recognition)

    原论文于2023.11.6撤稿,原因:缺乏合法的授权,详见此处 Abstract 在小样本学习中(Few-shot Learning, FSL)中,有通过利用额外的语义信息,如类名的文本Embeddi ...

  7. PHP header的几种用法

    PHP header的几种用法 定义:header() 函数向客户端发送原始的 HTTP 报头. 1. 跳转页面 header('Location:'.$url); //Location和" ...

  8. 嫌 OSS 查询太慢?看我们如何将速度提升 10 倍!

    背景 HDFS 是 Hadoop 生态的默认存储系统,很多数据分析和管理工具都是基于它的 API 设计和实现的.但 HDFS 是为传统机房设计的,在云上维护 HDFS 一点也不轻松,需要投入不少人力进 ...

  9. 《ASP.NET Core 与 RESTful API 开发实战》-- (第6章)-- 读书笔记(下)

    第 6 章 高级查询和日志 6.3 排序 RESTful API 在实现排序时应支持对集合资源的一个或多个属性进行排序 示例对 authors 资源按照其属性 Age 升序排序,再按 BirthPla ...

  10. Kafka-生产者、broker、消费者的调优参数总结

    生产环境下,为了尽可能提升Kafka的整体吞吐量,可以对Kafka的相关配置参数进行调整,以达到提升整体性能的目的. 本文主要从Kafka的不同组件出发,讲解各组件涉及的配置参数和参数含义. 一.生产 ...