XAF Blazor TabbedMdi
开源项目地址: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页,但保留了视图的状态
- 可以通过导航栏或窗口管理对视图进行切换

使用
基本
将BlazorTabbedMdi项目引入到解决方案中
在Startup类中将BlazorTabbedMdiModule模块添加到配置中

将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项目作为独立模块使用,不想直接修改,可以按照下面的步骤操作。
- 将MdiMainWindowTemplateComponent.razor与MdiMainWindowTemplateComponent.razor.cs文件拷贝到你的Blazor项目中,将其改名为CustomMainWindowTemplateComponent,修改并补全相应的命名空间。
- 在你的Blazor项目创建一个继承自MdiMainWindowTemplate的类(如:CustomMainWindowTemplate)
- CustomMainWindowTemplate.cs中的代码如下

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


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

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

- 通过修改CustomMainWindowTemplateComponent文件就可以实现自定义布局及样式
- 这种方式比较繁琐(在示例文件中包含了全部代码),如果没有独立使用的必要可以直接使用第一种方法
XAF Blazor TabbedMdi的更多相关文章
- XAF新手入门 - 模块(Module)
模块概述 谈到模块大家应该都不会感到陌生,不管是前端还是后端都有模块的概念,XAF中的模块概念与大多数框架中的模块概念是相通的.XAF模块首先是一个.NET类库,同时它还包含一个继承自ModuleBa ...
- XAF新手入门 - 前言
很多小伙伴在第一次接触XAF时,会被它的丰富功能及开箱即用的特点所吸引,即使在不了解XAF的情况下,也能够依葫芦画瓢创建一个功能丰富的应用,但当应用到实际项目中时,你会发现与之前的愿景差距很大,很多都 ...
- XAF新手入门 - 类型子系统(Types Info Subsystem)
类型子系统概述 类型子系统是XAF的核心概念,但我们平时却很少关注它,它集中存储了模块中的类型,它是生成应用程序模型(Application Model)的基础,它与XAF中其它的概念都有所关联,了解 ...
- 如何汉化XAF应用
这是一个入门级的问题,应网友请求,总结一下XAF汉化过程的几个关键点. 一.所有Dev的控件的汉化,Dev官方有汉化文件.点击下载15.2版本. 正版用户登陆至官网是有专门的下载界面的,并且可以参与汉 ...
- XAF视频教程来啦,已出7课
XAF交流学习群内的兄弟录制了视频,他没有博客,委拖我发至博客园,希望能让更多的开发人员受益.快速开发企业级应用的好工具! XAF入门01快速浏览 XAF入门02特点. XAF入门03 ...
- XAF 如何基于业务规则禁用属性
// Developer Express Code Central Example: // How to: Disable Property Editors Based on a Business R ...
- XAF 如何将数据库中Byte array图片显示出来
问题比较简单,直接上代码. private Image _Cover; [Size(SizeAttribute.Unlimited), ValueConverter(typeof(ImageValue ...
- XAF视频教程来啦,已出15课
第一到第七课在这里: http://www.cnblogs.com/foreachlife/p/xafvideo_1_6.html 视频地址:http://i.youku.com/i/UMTI5OTE ...
- XAF:如何让用户在运行时个性化界面并将个性化信息保存到数据库中 win/web/entityframework/xpo
本主题介绍如何启用管理模型差异(XAFML),并将设置存储在数据库中. 名词解释: 1.模型:XAF中把所有应用程序的结构都用模型来定义,比如列表,有哪些列,名称是什么,对应的字段名是什么,业务对 ...
- XAF点滴:很具体很用实用---处理三个小问题
以下内容全部为web版本的老模板风格下完成. 一.在编辑状态的详细视图下打印报表. 有些时候,需要在编辑状态下直接打印报表内容,官方默认是不允许这样做的.用Reflector查看源码,可以看到: De ...
随机推荐
- el-tree只展示前三个节点数据
后端也返回了第四等级,但是不想让他展示,可以这样解决只展示前三等级 // 获取room树 getRoomTreeList() { getRoomTree().then((res) => { // ...
- OCR文字检测与识别系统:融合文字检测、文字识别和方向分类器的综合解决方案
1. OCR文字检测与识别系统:融合文字检测.文字识别和方向分类器的综合解决方案 前两章主要介绍了DBNet文字检测算法以及CRNN文字识别算法.然而对于我们实际场景中的一张图像,想要单独基于文字检测 ...
- 【5】OpenCV2.4.9实现图像拼接与融合方法【SURF、SIFT、ORB、FAST、Harris角点 、stitch 】
相关文章: [1]windows下安装OpenCV(4.3)+VS2017安装+opencv_contrib4.3.0配置 [2]Visual Studio 2017同时配置OpenCV2.4 以及O ...
- 19.3 Boost Asio 多线程通信
多线程服务依赖于两个通用函数,首先boost::bind提供了一个高效的.简单的方法来创建函数对象和函数对象适配器,它的主要功能是提供了一种将函数和它的参数绑定到一起的方法,这种方法可以将具有参数的成 ...
- SpringCloud-06-Consul注册中心
Consul Server Consul 是由 HashiCorp 基于 Go 语言开发的,支持多数据中心,分布式高可用的服务发布和注册服务软件. 用于实现分布式系统的服务发现与配置. 使用起来也较 ...
- CSS背景设置与Emmet语法
CSS背景设置 通过CSS背景属性,可以给页面元素添加背景样式,页面元素指任意标签. 背景属性可以设置背景颜色,背景图片,背景平铺,背景图片位置,背景图像固定等. 背景颜色 一般默认值是:tran ...
- 【链表】链表的合并【经典面试OJ详解】【力扣21,力扣23】超详细的算法教程
链表的合并 导航小助手 说在前面 题目链接 链表结构 OJ21.合并两个有序链表 题目描述和算法分析 接口的完整实现代码 OJ23.合并K个升序链表 题目描述和算法分析 接口的完整实现代码 尾声 说在 ...
- .NET 云原生架构师训练营(模块二 基础巩固 引入)--学习笔记
2.1 引入 http协议 web server && web application framework .net 与 .net core asp .net core web api ...
- Python-集合的基本操作(set)
1. 前言 python中的集合和数学里的类似也是用于存放不重复的元素,它有可变集合(set)和不可变集合(feozenset)两种,集合的所有元素都放在一对大括号"{}"里(列表 ...
- Iot学习笔记记录
前言 2024.1.13 沙青图书馆 甚至一开始打成了2023年.各位新年快乐.有时间会写下2023的年度总结.不过在此要提前开一个博客,记录一下接下来学习Iot安全的记录了.实在是再不学就要被学弟学 ...