更新记录

FineUI 自 2008 年起持续迭代,每一次版本更新都源于真实项目的打磨与沉淀。

RECENT RELEASES

最近更新

v16.1.0 #220

新增

  • [Core/Java][示例] 新增后台修改表格列标题和宽度示例:Core RazorForms/Java 直接修改列属性,MVC/RazorPages 使用 UIHelper 的 HeaderText 和新增 Width 方法;支持修改、还原,并保留已有行数据及选择。
  • [Core-RazorForms/Java] 新增 Page_Init,在首次打开页面和每次控件回发时、模板处理前执行;Core 同时支持 Page_InitAsync。可在这里设置页面配置、准备模板数据,以及按网址参数查询并校验编辑对象;控件加载数据和事件处理继续放在 Page_Load 及对应事件中。
  • [Core-RazorForms/Java] 新增 PageContext.AbortPage(...) / PageContext.abortPage(...),可在 Page_Init 中提示参数错误或无权访问,并中止后续页面处理。调用后应立即 return;Core MVC 与原生 RazorPages 仍使用 return UIHelper.AbortPage(...)。
  • [Core-RazorForms/RazorPages/Java] Core 新增可选页面基类 FineUIPageBase,提供 IsPostBack 和 GetQueryValue、GetQueryIntValue、GetQueryLongValue、GetQueryBoolValue;Java 的同名基类补齐对应的 getQuery...Value 方法。可直接读取并转换网址参数,转换失败时使用指定默认值;记录是否存在及访问权限仍需由业务代码校验。
  • [Core] 新增 ClientCommand、PageContext.Execute / InvokeFunction,可用结构化动作和具名函数完成消息确认、隐藏窗体及回调,适用于严格内容安全策略(Content Security Policy,CSP)。例如确认后关闭活动窗体并回发,可设置 OkCommand = ActiveWindow.HidePostBackCommand("saved");Target=Top 的窗体也能回调原来打开它的页面。
  • [Core-RazorForms] 已有后台控件实例可直接调用 Grid.LoadData/AppendData、Tree.LoadData/ExpandNode、Window.Show、TabStrip.AddTab 等方法,无需再次按 ID 创建帮助类。MVC/RazorPages 继续使用 UIHelper。
  • [Core] 补齐 UIHelper.Button(id).Type(...) 和 UIHelper.Grid(id).RowGroup(enabled, field, options),可在 MVC/RazorPages 回发中切换按钮的普通、提交、重置行为,或一起更新表格行分组的开关、字段和选项。
  • [Core] 新增页面及全局配置 CspScriptsAllowUnsafeEval。开启 CSP 后,可明确控制是否允许 eval/new Function 执行业务脚本;未配置时三种 Core 模式均禁止。可信 Razor 模板内联脚本可自动获得本次请求的 nonce,业务数据中的脚本不会自动获得执行许可。
  • [Core/Java] 新增 PageContext.AddCss / PageContext.addCss,可在后台登记或替换当前页面的动态样式,适用于严格脚本 CSP。
  • [Java] 新增 PageContext.redirect、invokeFunction、invokeParentFunction 和 isFineUIAjaxPostBack,用于页面跳转、调用具名函数和判断回发;可视控件增加 hide()。新增 PageManager.current(),无需继承特定基类即可取得当前页面的配置入口。
  • [Core-RazorForms/Java] 浏览器控件实例新增 getDirtyKeys(),可查看后台累计修改过的属性。例如执行 F('Grid1').getDirtyKeys() 可辅助检查连续回发时哪些设置会被保留;返回数组的修改不会影响控件状态。
  • [JS/Core/Java] 树控件支持动态切换复选框及其显示范围、节点图标、选中与悬停样式、节点链接、文字选择、垂直滚动条及全部节点标题样式,切换时保留当前节点、勾选和展开状态。Java 补齐对应 setter/getter,Core 补齐 AjaxHelper 方法。
  • [JS/Core/Java] 树控件支持动态切换双击展开、同级单节点展开、多选及累加选择、右键选中节点、父子级联勾选。Core 可设置 ExpandOnDblClick、EnableSingleExpand、KeepCurrentSelection、ClickOnContextMenu、CascadeCheck 等属性;Java 提供对应方法,新规则从下一次操作开始生效。
  • [JS/Core/Java] Calendar、DatePicker 支持动态切换时间及分钟/秒显示、今天/确定按钮、确定后选择、层叠布局和范围面板独立导航,保留当前日期值。DatePicker 已打开或尚未创建的日历弹层都会采用新设置。
  • [JS/Core/Java] 日期、时间和下拉列表支持后台动态切换 EnableClickAction,Java 使用 setEnableClickAction。关闭后点击输入区不再弹出选择面板,右侧按钮仍可使用,当前选择保持不变。
  • [JS/Core/Java] 树控件新增 ClearData/clearData,可一次清空整棵树和全部选择,不触发选择事件;Core MVC/RazorPages 可调用 UIHelper.Tree(id).ClearData()。
  • [Core/Java] 表格新增 ClearData/clearData,明确清空数据;Core 新增 ClearSelections,清除包含其他分页在内的全部行和单元格选择。DeselectAllRows/deselectAllRows 仍只取消当前页可选行的选择。
  • [Java/Core] Java 组件补齐 EnableAjaxLoading、AjaxLoadingType、AjaxLoadingText、AjaxLoadingMaskText、ShowAjaxLoadingMaskText 的对应 setter/getter,可读取继承页面配置后的有效值。两端新增 ResetAjaxLoadingOptions/resetAjaxLoadingOptions,一次清除本控件的加载提示覆盖设置,重新使用页面配置。
  • [Core/Java] 控件属性表支持单项移除:Core 使用 RemoveAttribute / RemoveIFrameAttribute,Java 使用对应小写方法。IFrameAttributes 可单项更新;Java 新增 setIFrameAttributes,可整份替换或清空。更新 iframe 属性时会移除旧属性,并保留未修改的属性。
  • [Java] AccordionPane、GroupPanel、Panel、Region、Window 补齐 setIFrameUrl,可在后台更新 iframe 地址。
  • [Core] DropDownList.DataSimulateTreeLeafField 可按数据源中的布尔字段只允许叶子节点被选中;同时设置 DataEnableSelectField 时,后者决定最终是否可选。TriggerBox.TriggerCls 可直接指定自定义触发图标 CSS 类。
  • [Java] Grid、Tree、DropDownList、TimePicker 补齐 get/setSelectedRowID(Array)、get/setSelectedNodeID(Array)、get/setSelectedValueArray、get/setSelectedDate 及只读 getTimeFormatString。Grid 另提供 setSelectedCell(String[]);传 null 只清空单元格选择,保留已选行。
  • [Java] Tool 新增 get/setIcon、get/setIconUrl,面板和菜单项补齐 setIconUrl,提示字段补齐 setToolTipAutoHide。Tool 设置自定义图片地址时优先显示该图片,清空后恢复预定义图标。
  • [Core/Java] 可编辑 DropDownBox 新增 SetSelection/setSelection、ClearSelection/clearSelection、SetUserInput/setUserInput,分别用于成对设置选中值与文字、清空选择、用自由输入文字替换旧选择;多选文字中包含逗号时也能保留各项的对应关系。
  • [Java] 复选框列表和单选列表支持 setDataEnabledField,按数据源中的布尔字段控制每项是否可选;下拉列表支持 setDataGroupField,按字段分组。首次设置的文本、值、可选状态及分组字段会在后续回发的数据绑定中继续生效。
  • [Java] 工具条文本新增 setTextRaw/isTextRaw、setTextRawHtml/getTextRawHtml 和 text-raw-html 标签属性,可明确显示可信 HTML。
  • [Core] 编辑器 OptionItem.JsonValue 支持 JSON 布尔、数字、字符串、数组和对象,可在严格 CSP 下配置编辑器。原有 Value/PersistOriginal 写法继续兼容。
  • [Core] UIHelper.TextBox(...).RegexIgnoreCase(false) 可动态调整手写正则是否区分大小写;没有手写正则时不改变校验,内置 RegexPattern 仍按固定规则执行。

变更

  • [Core-MVC/RazorPages] 不兼容提醒:UIHelper 的文字、标题、提示及确认文字等 Raw 相关方法统一使用可选的可空布尔参数,例如 Text(text, bool? textRaw = null)。省略或 null 保留浏览器已有 Raw 标记,明确 false/true 才同时修改;需要恢复普通显示时显式传 false,普通控件仍按 EncodeText 设置显示。新增只改标记的 XxxRaw(bool) 和完整的 XxxRawHtml(RawHtml) 入口;后者传 null 清空内容并撤销 Raw。

    • Label、HyperLink、LinkButton 的旧 encodeTextOnServerSide 参数及服务器编码行为已删除。旧 Text(html, true) 重新编译后仍可能成功,但含义已从服务器编码变为按可信 HTML 显示,须逐处检查旧位置参数;确需服务器编码时显式调用编码函数,并核对客户端编码设置。升级后重新编译应用。Core RazorForms 控件属性、标签、流式创建及 F.js 直接 setter 不受本次变更影响。
  • [Core] 不兼容提醒:三种模式的首屏控件配置和页面操作统一使用 JSON,RazorForms 回发不再返回供浏览器直接执行的脚本。自行解析响应的代码(例如 AuthenticationTimeout)须改为读取 JSON 的 commands,页面跳转对应 page.redirect。升级或回滚时同时替换服务器 DLL 和客户端资源,并刷新已打开的页面。

  • [Core-RazorForms] 不兼容提醒:每次控件回发都会重新处理实际 Razor 模板,取得本次控件与事件声明;普通回发保留当前完整网址和查询参数。

    • 模板要读取的首次数据放在 Page_Init 的 !IsPostBack 分支;控件的数据绑定放在 Page_Load 的 !IsPostBack 分支。模板中的 DataSource、getter 仍会再次执行,依赖仅在 OnGet 创建的对象或带副作用的表达式须调整。
    • 动态事件及模板中不存在的富 HTML、动态字段格式,应由本轮模板或后台代码重新登记。会改变文字或参数的无名、重名表格命令,应设置唯一 CommandName,或每轮在 Page_Load 中重设。
  • [Core-RazorForms] 不兼容提醒:不再通过 PageManager 的 EnableRazorForms/EnableWebForms 属性、标签或流式设置切换单页模式,旧 setter 会明确报错。项目默认模式仍由全局配置决定;全局启用 RazorForms 时,原生页面须在模型类或共同基类上添加 [NoRazorForms]。普通独立上传、下载和 JSON 接口无需添加此标记。

  • [Core] 官方 RazorForms、MVC、RazorPages 示例和空项目,以及 AppBox、QuickStart,默认启用同源脚本与每请求 nonce,禁止任意内联脚本和字符串执行;类库本身不会自动开启 CSP。采用严格 CSP 的页面须使用结构化动作、具名函数及事件委托;必须依赖动态脚本的第三方编辑器仅在对应页面放宽策略。

    • MVC/RazorPages 的动态请求参数改用 Parameter.FromFunction/FromEventArgument/FromData;普通策略继续兼容旧业务脚本。
  • [Core-RazorForms] 回发按顺序执行;请求发出后暂时锁定文字输入与编辑区域,按钮操作可以排队,完成后恢复输入。错误、实际关窗或导航时清空待发操作;保存结果不明时不自动重发。

  • [Core-RazorForms] 不兼容提醒:控件事件不再接受 On...Parameter 或后台 Event.Parameters 附加字段。需要额外浏览器数据时使用 F.customEvent(name, payload),在 Page_CustomEvent 中读取;MVC/RazorPages 原生 Handler/Action 参数写法不变。

  • [Core-RazorForms/Pro/Java] 不兼容提醒:内置控件的带参事件改用具名 JSON 参数。框架自动生成的事件无需修改;手工拼接 paging$2$1、rowcommand$... 等旧参数的代码请改用控件公开事件或 F.customEvent。Java 普通控件事件通过 getArgument("字段名") 或专用事件参数读取,getArgument() 返回完整 JSON 文本;页面级 CustomEventArgs 的分段读取不变。

  • [Core-RazorForms/Java] 不兼容提醒:表格行命令的 ColumnIndex/getColumnIndex() 改为点击时从零开始的当前可见列位置,隐藏或拖动列后会变化。区分操作请使用 CommandName;按列名操作无字段或重复字段的列时,须显式设置 ColumnID/column-id,普通行命令无需为回发设置列名。

  • [Core-RazorForms] 不兼容提醒:不再自动生成 _fineui_column_... 作为服务器列名;显式 ColumnID 必须在整个列树中唯一,点号转下划线后也不能冲突。匿名控件的自动 ID 也可能变化;业务脚本直接引用旧自动编号的,请改为明确、稳定的 ID。

  • [JS/Core/Pro/Java] 不兼容提醒:FormRow 的列宽支持 auto,例如 ColumnWidths="100% auto" 让字段填满剩余空间、按钮保持自身宽度。Pro/Core 不再自动为按钮包一层 Panel;未指定列宽或设置 50% 50% 时,按钮也会占半行。需要窄按钮请使用 100% auto(MVC 为 .ColumnWidths("100% auto"));50% auto 不能代替这一写法。Java 原本就直接布局。

  • [JS/Core/Pro/Java] 基础默认值统一为:表格每页 20 行、时间选择器间隔 15 分钟、表格双击进入编辑、主题 pure_black。需要保持旧行为时,显式设置 PageSize、Increment、ClicksToEdit 或主题。

  • [Java/Core/Pro] 支持继承的属性未设置时采用表单或全局配置,明确设置时以本控件为准;FileUpload.ButtonText 未设置返回 null 并继承语言包,空字符串表示按钮不显示文字。

  • [Java] 不兼容提醒:尺寸、间距、步长、标签配置、列锁定能力等可继承属性采用可空包装类型。未设置的宽高、坐标、图片尺寸及按钮 TabIndex 返回 null,不再用 0 代替;读取后参与运算前须判空,setter 传 null 可撤销局部设置。升级后请重新编译。

  • [Core/Pro] 不兼容提醒:TabIndex 从 short? 改为 int?,TimePicker.Increment 从 short 改为 int。接收属性值的显式变量类型及旧程序集引用须对应调整并重新编译。

  • [JS/Core/Pro/Java] Tab、AccordionPane 的内容区固定无圆角,明确为内容区开启圆角时会报错;标题和内部普通面板仍可设置圆角。

  • [Core] 不兼容提醒:TabStrip.ActiveTab、Accordion.ActivePane 不再接受 null 或未加入当前容器的对象。请先把对象加入当前 Tabs/Panes 集合,再设置激活对象。

  • [Core/Java] 不兼容提醒:Accordion、Form、SimpleForm、Grid、RegionPanel、TabStrip、Tree 不支持直接配置 iframe,相关设置会明确报错。需要 iframe 时,请在容器中放置支持 iframe 的 Panel,或使用 Window、Tab、AccordionPane、GroupPanel、Region。

  • [Core/Java] 不兼容提醒:Grid.PageSizeOptions 使用正整数数组,仅在创建分页工具栏时生效;null 或空数组使用默认选项,非法项报错。Core 属性从 string[] 改为 int[],后台请将 new[] { "10", "20" } 改为 new[] { 10, 20 };流式数字参数及逗号分隔标签写法不变。

  • [Core/Java] 不兼容提醒:Calendar、DatePicker 的选中日期及上下限均按当前 DateFormatString 保存和读取;格式未包含的时间精度不再保留。需要时分秒时先设置格式,再设置日期。范围任一端赋 null 会清空整个范围;修改格式或分隔符时保留当前有效的两端日期。

  • [JS/Core/Pro/Java] 不兼容提醒:单选列表区分未选择与选中空值项:getValue() 未选择时返回 null,setValue(null) 清空,"" 表示选中了值为空字符串的真实选项,且可通过必选校验。判断未选择请使用 value == null,不要只比较空字符串。

  • [JS/Core-RazorForms/Java] 不兼容提醒:直接调用 DropDownBox.setText 会用自由文字替换旧选择。需要只更新选中项的显示文字并保留选中值时,请使用 setValue(value, text);多选文字中的逗号不再被误拆为多个选项。

  • [Java] 不兼容提醒:DataList.getSelectedValueArray() 从 List<String> 改为 String[],对应读取改用 length、[i];旧 getSelectedItems() 暂保留。清空多选请传 new String[0],避免 setSelectedValueArray(null) 在新旧重载间无法确定。

  • [Java] ColumnWidth、RegionPercent 的 getter 返回设置时的字符串,例如 "60%"、"20%",不再返回布局计算用的数值。

  • [Java] 不兼容提醒:图标及图片地址 getter 返回设置时的原始地址,例如 ~/images/a.png;需要已解析地址时显式调用 IconHelper.resolveUrl(...)。Image 同时设置预定义图标和自定义图片地址时,自定义地址优先。

  • [Java] 不兼容提醒:TriggerBox.setTriggerIcon / trigger-icon 只接受 None、Search、Clear、Date、ArrowDown、List 六种内置图标名。自定义 CSS 类名改用 setTriggerCls / trigger-cls。

  • [Java] TextBox 的 TextMode、InputType 分别保留设置值,非空 InputType 决定实际输入类型;仅设置 TextMode=Password 后,getInputType() 不再返回派生的 password。后台动态切换类型时,浏览器输入框也会同步更新。

  • [JS/Java] HtmlEditor.ToolbarSet 默认值统一为 Basic,与 Core/Pro 一致;需要完整工具栏的页面请显式设置 Full。

  • [Core-RazorForms] 不兼容提醒:表格回发事件不再自动取得上一轮设置的合计行。事件中需要合计值时,请从数据源重新计算并设置 SummaryDataArray。

  • [Core-RazorForms/Java][安全] 不兼容提醒:TextRaw、TitleRaw、ToolTipRaw 等 HTML 显示标记可跨回发保留;修改文字不会自动关闭原标记。标记来自浏览器,不能作为内容可信的证明;业务代码须验证 HTML 来源,必要时清洗后再显示。

  • [Core/Java] 不兼容提醒:TextRawHtml、TitleRawHtml 等可信 HTML 便捷入口传 null,统一为清空文字并关闭对应 Raw 标记。原来借 null 仅关闭 HTML 显示的代码,请改为 TextRaw=false(Java 为 setTextRaw(false));需同时换成普通文字时再设置 Text。

  • [Java] 不兼容提醒:首次打开页面时,Page_Load 在完整 Thymeleaf 模板求值后执行。模板中依赖 Page_Load 赋值的数据(包括页尾脚本中的表达式),须移到 Page_Init 准备;Page_Load 仍可操作已创建的控件。

  • [Core-RazorForms/RazorPages 示例] 不兼容提醒:官方页面基类统一为 PageBase,场景基类为 MobilePageBase、MultilangPageBase、UploadPageBase、WebUploaderPageBase、ThirdPartyEditorPageBase,AppBox 后台基类为 AdminPageBase。从旧示例继承基类的项目须同步修改类名和引用;MVC 控制器基类不变。

  • [示例] 六端省市县联动及省市表格示例改为保存固定编码、展示名称。照示例保存名称的项目,应将已有名称迁移为对应编码。

  • [Java] 不兼容提醒:手写 Regex 默认忽略大小写,例如 ^[a-z]+$ 可接受 ABC。需要区分大小写时设置 regex-ignore-case="false" 或调用 setRegexIgnoreCase(false)。

  • [Core] 不兼容提醒:内置 RegexPattern 按 F.js 的固定规则执行,例如 ALPHA_LOWER_CASE 拒绝 ABC;RegexIgnoreCase 只影响手写 Regex。RegexPattern.None 只清除内置规则,已设置的手写规则继续生效。

废弃

  • [Core] PageContext.RegisterPreStartupScript、RegisterPostStartupScript 标记废弃,旧调用仍可编译。初始化前的脚本请放在可信页面模板或外部 JS,控件创建后的动作使用结构化命令或具名函数;严格 CSP 下,原有 Pre/Post 及 RegisterStartupScript 的字符串脚本均不可执行。
  • [Java] Grid 的 ...RowId...、Tree 的 ...NodeId.../...NodeIds、列表的 ...SelectedValues/...SelectedItems 及 setSelectedValueArray(List<String>) 标记废弃。请改用 ID 大写的方法及返回 String[] 的 SelectedValueArray 方法;旧方法仍可调用。
  • [Java] FineUIPageBase 的 addCss、redirect、invokeFunction、invokeParentFunction 标记废弃,改用 PageContext 同名方法;旧 invokeClientFunction 改用 PageContext.invokeFunction。
  • [Java] FineUIPageBase.getCspScriptsNonceValue() 标记废弃。普通可信模板内联脚本已自动获得 nonce;确需显式取值时,可通过 PageManager.current().cspScriptsNonceValue() 读取。
  • [Java] 旧查询方法 getQueryParam、getQueryInt、getQueryLong 标记废弃,原行为保留;请改用以 Value 结尾的对应方法。
  • [Java] AbortPageException、ActiveWindow.hide*Reference、hideCallParentFunction 等旧入口标记废弃;页面中止改用 PageContext.abortPage(...); return;,延后执行的窗体动作改用 ActiveWindow.*Command。
  • [Java] Page_Get 保留兼容但不再推荐,页面初始化请迁到 Page_Init。旧方法按名称调用,编译器不会针对业务方法给出废弃警告。

移除

  • [Core] 不兼容提醒:移除接收 okScript 字符串的两个 UIHelper.AbortPage 重载。确认后关窗等动作改传 ClientCommand,例如 UIHelper.AbortPage(message, ActiveWindow.HideCommand())。
  • [Java] 不兼容提醒:移除 FineUIPageBase.hideComponent(id),改为取得对应控件实例后调用 Window1.hide() 等方法。
  • [Java] 不兼容提醒:移除 Alert、Confirm、Prompt、Notify 中返回脚本字符串的 getShowReference/getShowInTopReference/getShowInParentReference 重载。后台使用消息类的 show(...) 或实例 show();确认后的回调使用具名函数或 setOkCommand(...),客户端弹框可在具名函数中调用 F.alert 等方法。

修复

  • [Core-RazorForms] 修复后台直接修改列 HeaderText 后表头未重绘、修改 Width 未更新浏览器的问题;修改后的标题和宽度可在下一次回发继续读取。
  • [Java] 修复后台直接修改表格列属性后配置已更新、界面仍显示旧表头的问题;没有重新绑定数据时,使用已有行刷新表格。同时修复下一次回发丢失列渲染函数,导致“男/女”等文字退回原始数据的问题。
  • [Core/Java] 修复 Calendar、DatePicker 回发后单独修改范围一端无效、旧日期覆盖另一端,以及修改 Text 后再改格式导致日期回退的问题。Calendar 范围提交不再错误使用逗号;客户端清空后,后续回发不会恢复旧的初始日期。
  • [Core/Java] 修复表格重新绑定或清空后遗留旧行、跨页行及单元格选择的问题。带数据源的 ConfigColumns 遵守 ClearSelectionBeforeBinding;设为 false 时保留选择,需清除时设为 true 或调用明确清选方法。后台本轮指定的新选择在加载数据后生效。
  • [Core] 修复表格加载子行或追加数据时误改 RecordCount、导致总记录数变化的问题。
  • [Core] 修复下拉列表、单选/复选列表和 DataList 先设置选中值、后绑定数据时,SelectedItem/SelectedItemArray/SelectedText 返回旧项的问题;明确清空后,不再被随后加入的默认选中项重新选中。
  • [Core-RazorForms] 修复单选 DropDownBox 的空字符串 ID 在回发后被误当作未选择的问题,空 ID 与自由输入文字能够保持区分,IsUserInput 返回正确结果;单选 DropDownList 的后台清空也能正确生效。
  • [Java] 修复客户端 loadData 更新单选或复选列表,以及后台重绑下拉列表后,再次回发被拒绝的问题,省市等联动页面可连续操作。
  • [Java] 修复表格数字分页按钮配置在回发后丢失、数字框跳页可能返回 400 的问题。
  • [Core-RazorForms/Java] 修复后台动态创建或修改表格列后,下一次回发读不到完整列及修改结果的问题。动态换列时,新编辑器可复用被替换编辑器的弹层和子控件 ID;移除的编辑器不会继续参与回发。
  • [Java] 修复同一列的表头自定义属性、编辑器、过滤器不能同时生效的问题;声明顺序不再导致编辑或过滤配置丢失,分组表头中的子列也能正确关联所属表格。
  • [Core/Java] 未设置 EnableColumnEdit 时,后台读取的默认值与实际列一致:带编辑器的普通列和复选列为 true,其他列为 false。Java 列内的编辑器和过滤输入也可按控件 ID 在后台读取。
  • [JS/Core/Java] 修复 DataList 对象项缺少值时无法选择、连续追加空值项产生重复行标识的问题。
  • [Core] 修复树节点明确关闭复选框时,首屏或重新加载的节点仍显示复选框的问题。
  • [JS/Core/Java] 修复后台切换树外观时覆盖浏览器动态节点,以及退出微型模式后未恢复原有标题样式的问题。
  • [Core/Java] 修复顶层 Window 首次打开前更新 iframe 地址丢失,以及后台更新 IFrameAttributes 未作用于实际顶层 iframe 的问题;读取地址时也会取得真实窗体的当前地址。
  • [Core-RazorForms/Java] 修复回发中修改按钮 Type 后点击行为未更新的问题;Java 按钮改为 Reset 后只重置表单,不再错误触发原后台点击事件。
  • [Java] 修复按钮、工具按钮、菜单按钮在后台切换回发防连点选项后,浏览器仍使用旧配置的问题。
  • [Core-RazorForms/Java] 修复回发中修改 DropDownList.PersistItems、Tree.PersistNodes 后,下一轮仍按旧开关提交列表项或树节点的问题。
  • [Core/Java] 修复动态修改 FileUpload 按钮图标、NumberBox 触发按钮显隐和 TriggerBox 图标时,已渲染控件未同步更新的问题;明确设置 ShowEmptyLabel(false) 也能保留到下一轮回发。
  • [Core] 修复未上传文件、首次打开页面或非表单请求中读取文件列表和文件名时异常的问题,未上传时返回空结果;短文件名读取同时支持 Windows、Unix 路径。
  • [Java] 上传文件即使为零字节,只要有文件名也保留供业务校验;hasFile() 仍只判断首个文件是否非空。
  • [Java] 修复 Label 的 encode-text 不能正确切回编码显示的问题;关闭编码与 TextRaw 分别处理,encode-text="false" 不再自动把 isTextRaw() 设为 true。
  • [Java] 修复模板 css-style 不生效、标签属性中的 HTML 实体被重复编码的问题,例如 &lt; 现在正确显示为 <;表达式结果和后台业务字符串保持原值。
  • [Java] 修复 for 控件明确设置独立 name 后仍写回原模型属性、多个输入值不同时误报冲突的问题;仅修改 id 的控件继续正常绑定。
  • [Java] 修复 HtmlEditor 的当前内容、空字符串或 null 回发被拒绝的问题。
  • [Java] 修复多选 DropDownBox 的 getText() 返回 Java 列表格式的问题,显示文字不再带方括号。
  • [Java] 修复 FileSize、Ellipsis 等表格内置渲染器未正确格式化显示的问题。
  • [Core-RazorForms] 修复分部模板包含多个、匿名或嵌套控件时,显示不正确或重复加载数据的问题;修复日期样式字符串(如 2026-10-11T01:29:06Z)提交时被误解析为日期、恢复字符串属性报异常的问题。
  • [Core-RazorForms/Java] 修复部分动态控件连续回发时报错或丢失设置的问题,包括 Java 按钮颜色、面板内容、样式和下拉分组等。
  • [JS] 修复评分控件使用匿名渲染函数或函数工厂返回值时,自定义文字未正确显示的问题。
  • [Core] 修复只设置 Content-Disposition: attachment 的下载响应被误当作页面处理的问题。
  • [Core/Pro/Java 示例] 修复富文本编辑器加载未启用的可选资源、出现资源请求错误的问题。
  • [Core/Java 示例][安全] 表单和列表选中项汇总会编码字段名及业务文字,避免将输入内容直接作为 HTML 显示。
v16.0.1 #219

新增

  • [Core/Pro/Java] 统一控件级回发提示配置,支持 EnableAjaxLoading、AjaxLoadingType、AjaxLoadingText、AjaxLoadingMaskText、ShowAjaxLoadingMaskText,Java 使用对应的中划线标签属性。
    • 可为按钮、下拉列表等控件分别设置提示,单次 F.doPostBack 选项优先于控件配置,控件配置优先于页面默认值。
    • 三端均支持 disableControl 指定回发期间临时禁用的控件;传入 false 或空字符串可关闭临时禁用,动作控件未设置时默认禁用自身。
  • [Core] 补齐 UIHelper 控件帮助类的动态更新方法,可在回发中修改字段标签、必填和只读状态、长度与正则校验、提示信息、按钮确认框、树外观、表格选中单元格及列编辑状态等。
  • [Pro] 通用表格列支持更多展示方式。
    • RenderField 新增 RenderAsRowExpander 及双击、回车、展开时选中行等配置,可用客户端渲染函数生成行展开内容;新增 DataSimulateTreeLevelField,按数据中的层级显示模拟树缩进。
    • RenderCheckField 新增 RendererFunction,可按行数据隐藏或禁用复选框;原有模板列和服务端列继续兼容。
  • [Java] 补齐 PageManager 的具名流式配置方法,可直接设置主题、表单、表格、加载提示和水印等页面配置。单页首屏配置推荐放在 Page_Get,确保主题等设置在模板渲染前生效。
  • [Java] 表格新增 selectCell(rowId, columnId) 与 clearSelections(),支持按稳定行、列 ID 定位单元格,以及清除包含其他分页在内的全部行和单元格选择;清除选择不触发选择事件。
  • [Core/Pro/Java] 企业版交付包提供安装、卸载入口,自动切换项目引用并复制或清理开发授权;Core 同时支持 Windows、Linux 和 macOS。安装时检查已有文件,避免覆盖用户修改。
  • [四栈] 随项目提供的自定义主题工具新增自动监听:双击 res/themes/生成并监听主题.bat,先生成全部主题,再随配置文件保存自动更新主题样式。

变更

  • [Core/Pro/Java] 统一 F.beforeAjaxSuccess、F.beforeAjaxError 及 F.doPostBack 的 complete、success、error 回调参数与执行顺序。
    • 回调统一接收 (data, textStatus, xhr);Core / Pro 的成功数据为业务响应脚本,Java 为 JSON 文本,xhr.responseText 保留完整响应正文。Java 补齐单次 success / error 回调。
    • complete 在响应应用前执行;返回 false 可阻止后续回调、全局钩子、默认错误提示和响应应用,加载提示与临时禁用状态仍会清理。
  • [Core/Pro/Java] 文件上传与普通回发使用相同的成功、错误及完成回调,支持统一的错误拦截和超时处理。上传过程保留原文件输入框及所选文件;上传后需要清空选择时,调用服务端 Reset() 或客户端 reset()。
  • [Pro] NuGet 对 Newtonsoft.Json 仅要求 13.0.4 或更高版本,不再限制版本上限。升级到程序集版本不同的依赖时,须在 Web.config 中将 bindingRedirect 指向实际安装的版本。
  • [Core-RazorForms] 设计时文件按页面控件字段生成:没有控件字段的页面不再生成空的 .cshtml.designer.cs,并清理页面删除或移除控件后遗留的自动生成文件;手写文件保留。
  • [示例] 统一六套示例及配套项目中的普通日期显示为 yyyy-MM-dd;带时间的格式保留原精度,自定义日期格式和旧斜杠日期输入仍可使用。

修复

  • [四栈] 恢复未绑定数据字段的复选框列(RenderCheckField)在原始数据绑定时默认未选中,普通、单选和开关样式不再显示为空白;保留绑定字段空值及行绑定回调主动清空的行为。
  • [JS] 修复 HBox 在浏览器缩放或 CSS zoom 下自动高度被压缩、反复布局后高度漂移的问题,避免错误出现滚动条。
  • [JS] 修复小数内边距、边距和边框被取整后造成的布局偏移,以及缩放后表格、树滚动定位不准确的问题。
  • [JS] 修复树控件微型模式下,点击没有子节点的顶层菜单项不响应的问题。
  • [JS] 修复表格自定义日期渲染函数的显示文字或 HTML 被写入日期数据,导致重复显示、编辑判断或提交结果不正确的问题。
    • 日期列按 fieldFormat 保存、比较和提交,自定义 renderer 只负责显示;未指定格式时使用 yyyy-MM-dd,需要保留时间时显式设置为 yyyy-MM-dd HH:mm:ss 等格式。
  • [Core] 修复回发修改文本框 MaxLength 或字段 ToolTipAutoHide 时产生 JavaScript 错误。
  • [Java] 修复表单字段手写 regex 未正确转换为客户端正则、导致校验被跳过的问题;首屏声明和回发修改均生效。
v16.0.0 #218

新增

  • [示例] 六套示例在“布局 / Box”下新增 HBox、VBox 子项间隔页面,对照 BoxConfigSpace 与普通子项、末项边距的等效配置。现有示例和 AppBox 的统一间隔改用 BoxConfigSpace,去除冗余末项清零及无实际用途的尾部空隙;同步布局技能说明。

  • [JS/Core/Pro/Java] 工具栏统一支持 BodyPadding 主体内边距,默认布局的左右对齐、居中、填充和自动换行均考虑内边距;保留服务端 Container 继承及默认外观。属性仅创建时生效,新增六套对应示例。

  • [Java] FineUI.Java 首次发布,将标签声明控件、后台处理事件、控件状态自动往返的开发方式带到 Spring Boot。

    • 支持表单、表格、树、布局、窗体、数据绑定与校验;页面类支持 Spring 依赖注入,业务代码可直接调用服务与数据仓库。
    • 回发使用纯 JSON 增量响应,框架不执行脚本文本;控件状态无需保存在服务端 Session,回发请求按顺序处理。
    • 支持 Java 17+;Spring Boot 最低要求 3.5.16,支持 4.1.x;一个 Maven 依赖包含类库、前端运行时、主题和语言资源。
    • 提供完整示例、空项目、电影管理快速入门与 AppBox 权限管理框架,配套开发指南和 API 文档。
  • [Core/Pro/Java] 社区版通过公共软件包仓库分发:NuGet 包 FineUI.Core、FineUI.Pro,Maven 坐标 com.fineui:fineui-java。企业版使用客户专属版本,从客户本地源或私有源安装。

  • [示例] 官方示例、空项目、QuickStart、AppBox 和 fineui-skills 在独立仓库公开。17 个应用项目的自有源码采用 MIT 许可;FineUI 框架、二进制包和内嵌运行时仍适用各自许可,不属于这些项目的 MIT 授权范围。

    • fineui-skills 提供面向 AI 编程工具的官方知识包,按技术栈与开发模式整理控件、事件、安全及升级写法,不作为应用运行时依赖。
  • [Core-RazorForms/Java] 新增页面隐藏状态:C# 属性标记 [HiddenProperty],Java 字段标记 @HiddenProperty,即可跨回发保持,无需额外声明 HiddenField。

    • 支持可序列化的对象和集合,保留长整型与高精度小数;在 Page_Load 和事件处理前恢复。
    • 值经客户端往返,不是可信业务数据;权限、金额等仍须从服务端数据源核实。
  • [Pro] 新增 EnableImplicitPostBack 与 EnableImplicitChangeEvents 两个全局配置项,分别控制动作控件的隐式回发和表单变化事件的连带触发。

    • 类库默认均为 true,保持旧项目行为;官方示例、空项目和 AppBox 均设为 false。
    • 设为 false 后,声明对应服务端事件即可自动回发;其他控件发起回发时,只同步字段值,不连带触发其变化事件。显式 EnablePostBack / AutoPostBack 设置始终优先。
  • [Pro] 表格新增 RenderField.Commands 声明式行命令,支持文字、图标、确认框、参数、按行隐藏或禁用,以及按行数据打开编辑窗体。

    • 用 OnRowCommand 接收服务端事件,或监听客户端 rowcommand;客户端返回 false 可取消后续回发。新增 Grid.FindCommand,并校验回发中的行、列与命令。
    • LinkButtonField / WindowField 继续兼容旧页面;新示例统一使用 RenderField.Commands。
  • [Pro/Core-RazorForms/Java] 新增表格 GetSelectedDataKeys() / getSelectedDataKeys(),按稳定行 ID 关联选中行的数据键,避免用行下标查找。需同时声明 DataIDField 与包含该字段的 DataKeyNames;数据库跨页选择仍应按行 ID 查询服务端数据。

  • [Core-RazorForms] 新增 Grid.GetModifiedData() 和 GetMergedData(),与 Pro、Java 的方法入口统一;旧 ModifiedData / MergedData 属性继续兼容。无数据时三端均返回空集合。

    • Core、Java 读取完整合并数据需开启 IncludeMergedData;MVC / RazorPages 继续通过模型绑定参数读取编辑数据。
  • [Core/Java] 新增中止页面的标准方式:Core 从页面处理器返回 UIHelper.AbortPage(...),Java 可抛出 AbortPageException。参数无效等情况显示标准提示框,不再输出无样式的纯文本页。

  • [JS] F.validateForm / F.validateForms 支持 options 参数,例如 F.validateForm('form1', { messageBoxPlain: true });支持 target、messageBox、messageBoxPlain,旧位置参数仍可用。

  • [JS] Window 新增 setSaveStateControlIds(ids),可在客户端设置窗体关闭时回写值的控件。

  • [JS] Button 新增 setColor(color),支持在客户端切换语义色;传入空字符串可恢复默认色。

  • **[安全][Core/Pro]**新增 AllowDangerousScriptTag,控制是否继续把消息、确认文字等文案中的 <script> 当作代码。默认 true 以兼容旧项目,推荐迁移后设为 false。

    • 动态提示改在页面具名函数中生成,需要回传数据时使用 F.customEvent;不要把用户输入拼入脚本文本。官方示例和空项目已关闭此兼容入口。
  • **[安全][Java]**支持严格脚本内容安全策略(CSP),为可信 Thymeleaf 模板中的普通 <script> 自动添加每次请求独立的 nonce,无需逐个手写。

    • 官方 Examples、QuickStart、EmptyProject、AppBox 的 FineUI 页面默认启用,不放行 unsafe-inline / unsafe-eval;类库本身不强制开启,静态 HTML 与普通 Spring MVC 页面不在此处理范围内。
  • [Java] 提供表格撤销或确认编辑、更新单元格、增删行、分页排序、重载远程数据,以及窗体显示、关闭和刷新等服务端方法;消息统一通过 Alert、Confirm、Notify、Prompt 类调用,支持具名客户端回调。

  • [Java] 新增 fineui.grid-convert-long-to-string(默认 true),表格长整型数据以字符串传输,避免大整数在浏览器中丢失精度;提供 Thymeleaf 标签元数据,便于开发工具识别标签与属性。

变更

  • [JS/Pro/Core/Java] 普通表格的通用复选框点击后同步客户端当前值与界面,不新增 dirty 或编辑修改记录,并触发 datachange。

    • 不兼容提醒:updateCellValue 只有在启用单元格编辑时才触发 afteredit;普通表格的数据变化监听应使用 datachange。值未变化不触发这两个事件,forceUpdate 不控制事件静默,也不清除已有修改记录。
    • Pro 原服务端 CheckBoxField 的 HTML 值和 States 回发协议保持不变;普通通用列需要后台处理时仍显式提交自定义参数。运行时与读取当前值的新示例须配套更新。
  • [Core-RazorForms] 优化事件方法兼容处理:标签省略 Async 时保留异步优先,直接写完整 Async 方法名时精确调用;统一等待返回的 Task,支持无后缀的任务方法及 Task<T>。普通控件事件、Page_Load、Page_CustomEvent 共用规则,错误签名和缺失方法提供明确提示。

    • 不兼容提醒:完整名称 SaveAsync 不再优先查找 SaveAsyncAsync;普通控件方法缺失由静默跳过改为报错,async void、空任务和未约定返回类型须改为有效的 void 或 Task 方法。
  • [Core/Pro] 产品名称、程序集和公共命名空间统一为 FineUI.Core、FineUI.Pro(不兼容提醒)。

    • 升级时替换旧包或程序集引用,更新 using、类型全名和配置;Core 同时更新 Razor Tag Helper 的程序集引用。新旧程序集不可混用。
  • [Core] 最低运行环境提高到 .NET 8(不兼容提醒)。NuGet 对 Microsoft.AspNetCore.Mvc.NewtonsoftJson 只要求 8.0.31 或更高版本、不设上限;旧项目须先升级目标框架,较高版本的宿主还应显式引用与自身 ASP.NET Core 主版本一致的适配包。

  • [Core] AddFineUI 自动登记 JArray/JObject 模型绑定器,并在启用 RazorForms 时登记页面过滤器;不再需要手工添加,保留旧登记也不会重复执行。宿主仍需配置 MVC / RazorPages、AddNewtonsoftJson、UseFineUI 和路由。

  • [Core/Pro/Java] 客户端点击统一推荐 ClickHandler(Java:click-handler):属性只写函数名,函数首参为 event;OnClick / on-click 仍表示服务端事件。

    • 普通控件可在回发中更换或清空处理函数;TreeNode 回调为 (event, nodeId),随节点数据更新,不支持单独的增量 setter。同一控件不要同时声明 ClickHandler 与 click Listener。
    • 点击顺序为「表单验证 → beforeclick → click → 确认框与回发」;Core / Pro 的兼容 OnClientClick 在 beforeclick 后、click 前执行。验证失败时不执行点击回调,只有显式 return false 才取消后续动作(不兼容提醒)。
    • Core / Pro 的 OnClientClick 从 click 之后提前到之前,迁移时须核对取消逻辑和父菜单 ItemClick。Java 首发不提供 OnClientClick、隐式 <raw> 或全局 __doPostBack 兼容入口。
    • 六套示例和五个空项目模板均改用具名函数;按钮型链接使用 href="#" 并由点击处理器阻止默认导航,避免改变页面 hash。
  • [Pro/Core-RazorForms/Java] 页面级自定义回发统一使用 F.customEvent(name, payload),由 Page_CustomEvent 接收;支持基本值、对象和数组,Pro 补齐相同入口。

    • Core RazorForms 的客户端临时数据推荐由此传入;需要绑定到命名表单字段时使用 F.doPostBack({ eventName, params })。Java 不提供 params 通道;MVC / RazorPages 继续使用各自的 OnClickParameter。
  • [Pro/Core-RazorForms/Java] 普通控件回发参数以 click、change 等客户端事件名开头,Grid、Tree、Window 的参数格式统一。

    • 不兼容提醒:Pro 不再接收空默认参数及 Command、Page、ClearIcon 等旧标识;自行拼接底层回发参数的代码须迁移。Java 按服务端页面声明派发事件,不向浏览器暴露后台处理方法名。
  • [四栈] 回车聚焦属性指向按钮时只聚焦,不再自动点击(不兼容提醒)。需要回车点击按钮时使用 NextClickControl,Java 为 next-click-control,JS 为 enterClickControl。

  • [Pro] 表格列未设置 ColumnID 时优先使用 DataField,与 Core 保持一致;依赖旧自动列名的客户端代码应显式设置 ColumnID。

  • [四栈] 表格检查分组列、叶子列和隐藏列的 ColumnID 是否唯一。F / Core / Pro 默认警告,可用 gridStrictColumnIdValidation / GridStrictColumnIDValidation 开启严格检查;Java 始终严格检查。自动列名会避让已有名称。

  • [Core/Pro/Java] 内嵌资源地址改为按文件内容生成缓存摘要,内容未变时可跨页面与 iframe 复用缓存,内容改变时自动更新地址。

    • 不兼容提醒:Core / Pro 的 res.axd 不再接收旧 t 参数,Java 内嵌资源从 /F/ 迁至 /FineUI/;请使用框架生成的地址,并在部署后刷新旧页面。业务自己的 /res/ 文件不受此规则管理。
  • [Core/Pro/Java] 新授权文件名前缀统一为带点产品名,如 FineUI.Core.lic.dev.config;旧前缀仍可读取,新旧文件并存时优先使用新文件。

  • [Pro] 本地调试模式下 __FSTATE 以明文 JSON 传输,便于检查;发布态保持混淆编码。混淆不等于加密或防篡改。

  • [示例] 图片与文件下载统一为公共 Download 入口:图片白名单内的文件可内联显示,其他文件强制下载;上传文件存放在不可直接访问的目录,WebUploader 增加上传归属校验。

  • [JS] 回发请求改用原生 fetch;统一手风琴、面板、表格和树的展开折叠动画,减少快速连续操作造成的状态与显示异常。

废弃

  • [Core/Pro] 表格 SelectedRowIndex / SelectedRowIndexArray 标记为过时;改用 SelectedRowID / SelectedRowIDArray,读取数据键用 GetSelectedDataKeys()。行事件参数中的 RowIndex 仍可用于定位事件发生的行。
  • [Pro] GetModifiedDict()、GetDeletedList()、GetNewAddedList() 标记为过时;改用 GetModifiedData(),按 status(modified / newadded / deleted)处理,每条记录直接携带 id。
    • 新方法返回原始 JSON,清空数字单元格时得到空字符串;写入数据库或 DataTable 前须转换为适当的空值。读取编辑数据应在重新绑定表格之前完成。
  • [Core/Pro] TreeNode.OnClientClick 及可替代的 OnClientBlur、OnClientTriggerClick 等属性标记为过时;分别改用 ClickHandler 或对应事件的具名 Listener。其他控件的 OnClientClick 本版继续兼容。
  • [Pro] PageManager.CustomEvent(标签 OnCustomEvent)与 GetCustomEventReference 废弃;改用 F.customEvent 和 Page_CustomEvent,旧入口仍可运行。
  • [Core] ExcludedURLs 废弃但继续兼容;中间件仅缓冲需要加工的 HTML,图片、文件和其他响应直接输出,降低大文件下载时的内存占用。

移除

  • 移除对所有 IE 浏览器的支持,以及 F.isIE8()、F.isIE89()、F.isIE9()、F.isIE();请使用 Chrome、Edge、Firefox、Safari 等现代浏览器(不兼容提醒)。

修复

  • [JS/Core/Pro/Java] HBox、VBox 显式设置子项间隔为 0 时,正确清除布局边距并覆盖旧边距配置,避免将数值 0 当成未设置。

  • **[安全][Pro]**修复 EnableFStateValidation 状态签名校验。启用后必须显式配置 <machineKey> 的 validationKey,不可使用 AutoGenerate;多节点部署须保持密钥一致(不兼容提醒)。默认未开启此项的项目不受影响。

  • **[安全][Core-RazorForms]**页面过滤器中止请求后,不再执行控件事件,避免权限检查已拒绝请求而业务写入仍然发生。

  • **[安全][Core/Pro]**补齐可信 HTML 标记的回发处理和脚本字符串转义边界,修复部分提示、文本在回发后显示或编码不正确的问题。

  • [JS] 修复大量列、多级分组表头在混合列宽下与表体错位的问题,横向滚动与锁定列下也保持对齐(STARK11号 - https://t.zsxq.com/sJSCQ)。v15.2.0 的修复只覆盖了部分等宽场景,本次补齐。

  • [JS] 修复表格日期列解析时丢失时分秒、被显示为 00:00 的问题,兼容带时间的斜杠日期字符串。

  • [JS] 修复 HiddenField 未加入表单字段集合、导致表单重置时未被清空的问题。

  • [Core] 修复表格跨页保持选中时回发报错,以及 iframe 属性修改未完整同步到客户端的问题。

  • [Core] 修复回发修改 Accordion 的 ActivePaneIndex 后,客户端未激活对应面板的问题。

  • [Pro] 修复 DropDownList 空值选项的选中状态,以及表格列提示被重复 HTML 编码的问题。

  • [Core/Pro/JS] 统一 HyperLink / LinkButton 的禁用行为:禁用后不可点击或通过 Tab 聚焦,启用后恢复;清空超链接地址时移除旧链接。

  • [Java] 修复动态控件属性跨回发丢失、列表选择更新遗漏、通知关闭按钮配置未生效,以及网址数据源首次自动加载不一致的问题。

  • [示例] 修复清空数字单元格后保存报错、两个触发器输入框的延迟搜索失效,以及子目录部署时查看源代码或文件回显地址错误的问题。

v15.2.0 #217
  • [安全] 修复 <raw> 标签的 XSS 隐患,换用更安全的方式输出"可信的 HTML"。
    • 老问题:以前想让一段文本按 HTML 显示(不转义),要写成 <raw>...</raw>。但如果这段文本来自用户输入或数据库,就能塞进 <script> 等脚本代码,存在 XSS 风险。
    • 新思路:把"这段 HTML 可信"的判断交给开发者在代码里明确声明,用户填的普通文本永远不会被当成可信 HTML,从根上堵住了这个漏洞。
    • 新增声明"可信 HTML"的写法,用来替代 <raw>。
      • 后台 C#:用 new RawHtml("<b>...</b>") 包裹一下;给控件赋值如 Label1.TextRawHtml = new RawHtml(...);弹出消息框如 Alert.Show(new RawHtml(...))。
      • 页面标签:Pro 版用单属性 TextRawHtml="<b>加粗</b>",Core 版用 _TextRawHtml="<b>加粗</b>",或者 TextRawHtml="@(new RawHtml("<b>加粗</b>"))"。
      • 前端 JS:用 F.rawHtml('<b>...</b>') 传给文本、标题、提示等属性。
    • 新增全局开关,可彻底关闭 <raw> 老写法。
      • 新增配置项 AllowDangerousRawTag,默认开启(兼容老代码);推荐设为 false 把 <raw> 彻底关掉,更安全。
      • 关闭后页面里若还残留 <raw>,浏览器控制台会提醒一次,引导你改用新的写法。
    • 示例项目已全部从 <raw> 改为新写法,并默认关闭了 <raw>,作为安全配置的范例。
    • 新增文档:FineUICore开发指南/安全策略(HTML 编码);安全策略(用 RawHtml / F.rawHtml 安全输出 HTML)。
  • [安全] 修复可信 HTML(F.rawHtml / RawHtml)在跨窗口(iframe)弹层中显示为 [object Object] 的问题(腊八 - https://t.zsxq.com/onDJF)。
    • 现象:iframe 子页里用 F.alert / F.confirm 等弹到父/顶层窗口(target 为 _parent、_top),且标题或内容用 F.rawHtml(...) 声明可信 HTML 时,显示成了 [object Object]。
    • 根源:框架靠 instanceof 判断是不是可信 HTML,而 instanceof 按窗口隔离——子窗口创建的对象拿到父窗口判断会失败,于是被当普通对象输出。同窗口(不带 target)不受影响。
    • 修复:改用不受窗口隔离的判断方式,跨窗口也能正确识别;用户输入仍无法伪造,安全性不降级。
  • [安全] 菜单项文本改为默认 HTML 编码,之前把 HTML 写进菜单项文本的用法需要显式声明为“可信 HTML”(不兼容提醒!)。
    • 涉及控件:菜单项(MenuItem)、菜单按钮(MenuButton)、菜单超链接(MenuHyperLink)、菜单文本(MenuText)、菜单复选框(MenuCheckBox)。
    • 现象:升级后,菜单项文本里写的 HTML(如 <div>、<span>、<i>、<img> 等)不再按 HTML 渲染,而是被当成普通文字原样显示出来。
    • 原因:本次安全加固把菜单项文本纳入“默认 HTML 编码、开发者确信可信时才原样输出”的统一机制;而菜单项文本此前是“首次渲染时原样输出、不编码”的历史特例,故受影响。
    • 升级办法(仅对开发者确信可信的 HTML 这样声明;来自用户输入/数据库的内容不要声明,让其保持 HTML 编码):
      • [JS] 把 text: '<i>...</i>' 改为 text: F.rawHtml('<i>...</i>')。
      • [Pro] 标签写法把 Text="<i>...</i>" 改为 TextRawHtml="<i>...</i>";后置代码把 xxx.Text = "..." 改为 xxx.TextRawHtml = new RawHtml("...")。
      • [Core] 把 .Text("<i>...</i>") 改为 .TextRawHtml(new RawHtml("<i>...</i>"));标签写法(RazorForms/RazorPages)把 Text="<i>...</i>" 改为 _TextRawHtml="<i>...</i>"(或 TextRawHtml="@(new RawHtml("..."))")。
  • [安全] 单选框列表、复选框列表的列表项支持声明“可信 HTML”(谭晓 - https://t.zsxq.com/uDDcT)。
    • 列表项 RadioItem / CheckItem 新增 TextRaw、TextRawHtml 属性;列表控件新增 DataTextRaw 属性——数据绑定(DataBind)时把整列文本按可信 HTML 输出。
    • 三种数据绑定方式在功能和安全性方面等价(DataSource + DataBind + DataTextRaw、OnItemDataBound、手工构建 Items),模版内的数据字段需要自行 HtmlEncode 转义。
    • 新增示例:表单控件/选择框/单选框列表(图标选项,可信 HTML)。
  • 表格分页工具栏新增窄屏自动简洁分页模式(251081362)。
    • [JS] 为表格新增pagerAutoSimpleMode属性
    • [JS] 新增全局配置项gridPagerAutoSimpleMode;分页栏宽度不足时,完整分页器自动降级为“上一页 + 当前/总页 + 下一页”的简洁形态,拉宽后自动还原(默认关闭)。
    • [Core/Pro] 为Grid新增PagerAutoSimpleMode属性,为PageManager和配置文件新增全局配置项GridPagerAutoSimpleMode。
    • 新增示例:表格/分页工具栏/窄屏自动简洁分页。
  • 表格新增客户端事件displaytypechange,显示模式(表格/卡片)切换时触发(木南 - https://t.zsxq.com/iDJb3)。
    • [JS] 签名(event, newDisplayType, oldDisplayType);窄屏自动切换(responsiveCardSize)与手动 setDisplayType 均会触发。
    • [Core/Pro] 该客户端事件通过Listeners集合挂接,无需新增控件属性。
  • 修复可编辑日期列在 storeDateAsString=false 时,用鼠标重选“同一天”(未做任何修改)也被误标记为已修改(左上角小红标)的问题(wmdyj - https://t.zsxq.com/0y50E)。
    • [JS] 根源是时区换算:日期列(FieldType=Date)的值,服务端按 UTC 时间下发(形如 2026-06-19T00:00:00+00:00,即 UTC 的零点),浏览器换算成本地时间后,在东八区就变成了当天的 08:00;
    • [JS] ...而用户点日历重新选一次,选出来的是当天的本地 00:00。同样是 6 月 19 日,一个带 08:00、一个是 00:00,框架按“时间戳”判断两者是否相等时就认为变了,于是误判为已修改。
    • [JS] 修复:日期列“是否被修改”的判定,改为按“列显示的日期格式”比较(本例只显示到“天”,08:00 与 00:00 都算同一天,故不再误判);对含时分秒的日期时间列仍按完整时间比较,能正确识别真正的修改。
    • 新增示例:表格控件/单元格编辑/杂项/日期列编辑(重选同一天不标记为已修改)。
  • 日期范围选择支持左右面板独立切换(放牛娃 - https://t.zsxq.com/OcLDq)。
    • [JS] 为Calendar和DatePicker新增independentRangePanels属性,默认关闭。
    • [JS] 开启后,日期范围(DayRange)、月份范围(MonthRange)、年份范围(YearRange)的左右两个面板可以分别切换,不再强制相邻;左右非法交叉时相关导航按钮自动禁用。
    • [Core/Pro] 为Calendar和DatePicker新增IndependentRangePanels属性。
    • [JS] 统一浮层的落点位置:点击左右任一面板标题栏的年份/月份,浮层在该面板就地展开(独立与联动两种模式行为一致)。
    • 新增示例:日期控件/日期范围控件/日期范围(范围面板独立切换)。
  • 修复点击日期控件标题栏的年份/月份时,弹出浮层里高亮的年月不正确的问题。
    • 浮层里的年/月网格本质是“跳转导航”,应该高亮正在显示的年/月,而不是当前Calendar选中的日期。
    • 高亮改用独立的浅描边样式(弱于选中项的焦点样式),避免与“选中的日期”混淆。
  • 增强示例项目的文件上传校验,作为安全上传的范例。
    • 在示例基类中新增 ValidateUploadFile 方法,统一做“扩展名白名单 + 文件大小上限(默认 2MB)”校验,并返回具体的失败原因(类型不符 / 文件过大 / 文件为空)。
    • 所有上传示例调用基类的公共方法;多文件上传示例改为逐个校验、跳过非法文件并汇总提示。
    • 上传图片回显改为“三步安全上传”范例。
      • 扩展名白名单校验;
      • 用时间戳重命名,避免覆盖与文件名注入;
      • 文件保存到不可直接访问的目录,再通过公共下载处理器带正确的 Content-Type 输出(即使上传了 .html 等文件,浏览器也永远不会把它当页面/脚本执行)。
        • [Core] 保存到 wwwroot 之外的 App_Data/upload
        • [Pro] 保存到 App_Data/upload
    • 新增公共图片下载入口(图片扩展名白名单 + 防路径穿越 + 正确 Content-Type),基类新增 SaveUploadFile / GetImageUrl 辅助方法。
      • [Core] MVC 为 HomeController.ImageDownload
      • [Core] RazorForms/RazorPages 为 Home/ImageDownload
      • [Pro] common/ImageDownload.ashx
  • [Pro] 修复 DropDownList 空值项(Value="")导致的任意回发都会误触发 SelectedIndexChanged 的问题(曹** - https://t.zsxq.com/NUdIK)。
  • 表格新增列属性 showTooltipWhenTruncated:单元格提示仅在文本被列宽截断(出现省略号)时才显示,未截断的短内容鼠标悬停不弹提示(默认 false,向后兼容)(笑疯 - https://t.zsxq.com/pMPsE)。
    • 需配合 showTooltip=true,仅 tooltipType=qtip 时有效(title 类型走浏览器原生、无法根据单元格文本是否被截断动态显示)。
    • [JS] 提示属性仍放在内层 <span> 上并追加 data-qtip-truncated 标记,鼠标悬停时检测省略号容器(.f-grid-cell-text)的宽度以决定是否弹出提示;
    • [Core/Pro] 新增全局配置项 GridShowTooltipWhenTruncated 与列属性 ShowTooltipWhenTruncated,支持 PageManager 全局设置、表格级别和列级别的覆盖。
    • 新增示例:表格/杂项/提示信息(仅截断时显示)。
  • 修复下拉列表多选标签模式的输入框在紧凑/小字体/大字体/大间距等显示模式下高度不正确的问题(Hui - https://t.zsxq.com/FInyc)。
  • 修复日期/时间控件在 Firefox 浏览器下(Chrome 正常)时间选择列(时/分/秒)显示为空白的问题(herry)。
  • 修复 Firefox 浏览器下下拉列表、菜单、日历等区域的自定义细滚动条未生效(显示为浏览器默认滚动条)的问题。
  • 修复表格(例如右侧锁定列)数据由多变少、纵向滚动条消失后,表头仍残留滚动条补偿宽度(margin-right),导致表头与数据列错位的问题(stone磊 - https://t.zsxq.com/DeTXZ)。
v15.0.3 #216
  • [JS] 修正 esbuild 编译目标为 es2022,导致打包后的产物保留 ES2020 新语法(空值合并 ??),在旧版 WebView 解析阶段出错(Alan - https://t.zsxq.com/mG100) 。
    • 修复:编译目标(bundle 与 minify)统一降为 es2015。
  • [JS] 修正老版本Chrome浏览器可能报错 e.columnId.replaceAll is not a function。
    • esbuild 编译目标只降级新语法,不会自动补齐运行时新增的方法/静态函数;老旧 WebView 调用 String.prototype.replaceAll 等方法时报错。
    • 修复:新增运行时 polyfill,补齐 replaceAll、Array.includes、Object.values/entries、padStart/padEnd 等 ES2015+ 运行时 API,兼容旧内核。

RELEASE ARCHIVE

历史版本