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 ...
 
随机推荐
- C#对象属性浅拷贝和深拷贝
			
对象属性和字段拷贝的几种方式 微软提供了浅拷贝 对于值类型,修改拷贝的值不会影响源对象 对于引用类型,修改拷贝后的值会影响源对象,但string特殊,它会拷贝一个副本,互相不会影响 自己实现深拷贝,我 ...
 - 从零开始配置vim(26)——LSP UI 美化
			
之前我们通过几个实例演示如何配置其他语言的lsp服务,相信各位小伙伴碰到其他的编程语言也能熟练的配置它对应的lsp服务.本篇讲作为一个补充,我们来优化一下LSP 相关的显示 配置 UI 原始的 lsp ...
 - Walrus 0.5发布:重构交互流程,打造开箱即用的部署体验
			
开源应用管理平台 Walrus 0.5 已于近日正式发布! Walrus 0.4 引入了全新应用模型,极大程度减少了重复的配置工作,并为研发团队屏蔽了云原生及基础设施的复杂度.Walrus 0.5 在 ...
 - 7.1 Windows驱动开发:内核监控进程与线程回调
			
在前面的文章中LyShark一直在重复的实现对系统底层模块的枚举,今天我们将展开一个新的话题,内核监控,我们以监控进程线程创建为例,在Win10系统中监控进程与线程可以使用微软提供给我们的两个新函数来 ...
 - CF1010C Border 题解
			
题目传送门 前置知识 最大公约数 | 裴蜀定理 简化题意 给定一个长度为 \(n\) 的序列 \(a\),求 \((\sum\limits_{i=1}^{n}d_ia_i) \bmod k\) 一共会 ...
 - React axios 使用 http-proxy-middleware 解决跨域问题小记
			
壹 ❀ 引 在上篇bug分析的记录文中,提到axios可做到取消接口请求,所以想写一篇关于axios.CancelToken使用以及原理分析的文章(主要是自己好奇到底如何做到的取消).在准备工作阶段, ...
 - JS leetcode 存在重复元素 II 题解分析,记一次震惊的负向优化
			
壹 ❀ 引 整理下今天做的算法题,题目难度不高,但在优化角度也是费了一些功夫.题目来自219. 存在重复元素 II,问题描述如下: 给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i ...
 - Sunnyui画曲线溢出错误
			
之前用sunnyui做展示数据库数据曲线的时候.偶然会报溢出错误,也不报错错误在哪,就是直接程序都跑不动了. 后面发现 设置曲线上下限的时候,当上下限一样的时候就会导致溢出错误.sunnyui的曲线也 ...
 - NC20259 [SCOI2007]降雨量
			
题目链接 题目 题目描述 我们常常会说这样的话:"X年是自Y年以来降雨量最多的".它的含义是X年的降雨量不超过Y年,且对于任意 Y<Z<X,Z年的降雨量严格小于X年. ...
 - spring boot整合spring security自定义登录跳转地址
			
说明 在博客用户登录后我想跳转到各自用户的博客首页,我们知道这个地址是动态的. 例如: http://localhost:8080/blog/zhangsan, 每个用户地址不一样.这时候我就用到了自 ...