# demo **Repository Path**: wangfs763/demo ## Basic Information - **Project Name**: demo - **Description**: 例程或文档 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-04-08 - **Last Updated**: 2024-04-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # DotNet 类库 该仓库为实用性相对较高的类库。 ## 1、ObjectModel 数据模型库,该库定义了数据模型基类 BaseViewModel,以及衍生基类。该库的核心功能是实现了一套用于处理WPF界面数据模型的机制,功能包括:数据校验、单位转换、显示格式等。 1. ObservableObject 数据模型基类,实现了接口 INotifyPropertyChanged,监听了 UnitSystem 单位切换事件,提供了资源释放接口 Release。 2. BaseViewModel、BaseViewModelWithOwner 提供 Set 接口给子类给字段赋值后触发值改变事件,返回 **!ObservableObject.IsDeserializing**。 3. BaseModel、BaseModelWithOwner 该基类用字典存储属性,提供 Get 从字典中存储属性,提供 Set 修改存储的属性值。 4. ModelCollectionWithOwner 数据绑定集合基类,带有 Owner 属性。 5. ModelCollectionChildWithOwner 数据绑定集合基类,带有 Owner 属性,且集合元素也带有 Owner 属性。将元素添加到集合中时,**自动修改元素的 Owner 属性**。 ### 1.1、特性类 使用特性的核心类是 ViewModelProxy,或者应该是 ComplexViewModelProxy<>。后者可以将数据模型中的自定义属性类型进行代理,前者只能代理基础数据类型。被代理后的类型,绑定到 WPF 界面后就可以自动应用数据校验、单位转换、显示格式等。当然,为了达到预期效果,需要在数据模型的属性上使用特定的 Attribute。这些 Attribute 分为2个类别,一个负责显示,一个负责校验。使用方式可参考Test\ModelProxyTest.xaml。 1. 负责转换与显示 - **FormattedAttribute**:可以将浮点数按照一定的格式进行显示。 - **LengthAttribute**:如果属性表示长度物理量,支持切换公英制的同时,还可以按一定的格式进行显示。 - **AngleAttribute**:如果属性表示角度物理量,支持按角度、弧度进行切换,并按一定的格式显示。 2. 负责校验 - **RangeAttribute**:用于限制属性的编辑范围,支持包含与不包含,如 "(0, 88.8]"。 - **RegexAttribute**:正则表达式校验,顾名思义,需要输入合适的正则表达式去校验输入。 为了支持单位转换,定义了 **UnitSystem** 类。该类中定义了不同类型数值的显示格式,以及转换技术接口。如果默认的显示格式不满足需求,可以通过对应的静态函数进行修改。 通过显示与校验特性的组合使用,基本可以满足日常需求。 ### 1.2、Xaml支持 如果通过 Xaml 实现相关功能,则**不建议**在数据模型上使用特性类,可能造成校验不统一等问题。 该库提供了自定义的绑定标记,通过对应的绑定标记即可**自动**有**数据校验**、**单位转换**、**显示格式**、**输入限制**等功能。 库中添加的自定义的数据绑定标记如下表: | 标记 | 作用 | | ------------- | ------------------------------------------ | | **NBindingL** | 绑定的属性表示长度,可以切换公、英制。 | | **NBindingA** | 绑定的属性表示角度,可以切换度、弧度。 | | **NBindingF** | 绑定的属性表示普通浮点数,但是有显示格式。 | | **NBindingI** | 绑定的属性是整数。 | 在 TextBox上使用以上提到的依赖项属性后,该 TextBox 将只能输入数值,输入的同时将进行数值校验。鼠标滚轮可以修改值。未选中的情况下±1,按住 Alt 键调整光标位置的数值,按住 Ctrl 键可以循环调整;有选中文本的情况下,针对选中部分进行修改,按住 Alt 键对每一位数值进行调整,按住 Ctrl 键可以循环调整。 ### 1.3、使用方式 - WPF 中使用 在 xaml 中使用库中的绑定标记 NBinding,不需要其它设置(Rule、Converter 等),也不需要在属性上使用 Attribute。 - WinForm 中使用 只能使用 代理类 ComplexViewModelProxy 创建数据源用于绑定。 ### 1.4、扩展 如果需要扩展校验规则等,按如下步骤操作: 1. 添加自定义绑定标记,继承 **NBindingT**。 2. 为了完成上一步,需要先定义一个继承 **ValueConverter** 的转换器。 3. 为了让数据正确显示、存储,在上一步中需要重写 **CreateFormat()** 接口,返回一个自定义的继承自 **UnitAttribute** 的特性。 ### 1.5、示例 效果预览 ![ObjectModel](/Images/ObjectModel.gif) 1. 定义数据模型 ```c# public class SubModel : BaseViewModel { private string m_StrValue; private double m_Value1 public string StrValue { get => this.m_StrValue; set => this.Set(ref this.m_StrValue, value); } [Range("(0, 100]")] public double Value1 { get => this.m_Value1; set => this.Set(ref this.m_Value1, value); } } public class DataModel : BaseViewModel { private double m_Value; private SubModel m_model; [Length, Range("[10, 100)")] public double Value { get => this.m_Value; set { if (!this.Set(ref this.m_Value, value)) return; // ... } } public double Length { get; set; } public SubModel { get; set; } = new SubModel(); } ``` 2. 数据绑定 - WPF 中的数据绑定 ```xaml ``` 可以在调用窗口时给窗口的 DataContext 赋值,如: ```c# Window win = new Window(); ComplexViewModelProxy model = new ComplexViewModelProxy(new DataModel()); win.DataContext = model; win.Show(); ``` - WinForm 中的数据绑定 在 WinForm 中使用只能通过库中定义的 Attribute 实现数据校验、单位转换、显示格式等。 ```c# public class DemoForm : Form { public DemoForm() { this.InitializeComponent(); DataModel dm = new ComplexViewModelProxy(new DataModel()); this.textBox1.DataBindings.Add("Text", dm, "Value"); this.textBox2.DataBindings.Add("Text", dm.SubModel, "StrValue"); this.textBox3.DataBindings.Add("Text", dm.SubModel, "Value1"); } } ``` ### 1.5、其它附加依赖项属性 - FocusOperations 中的附加依赖项属性 | 属性 | 说明 | | -------------------- | ------------------------------------------------------------ | | SelectAllWhenFocused | 在布局容器中使用,容器中的 TextBox 在获得焦点后全选内容。 | | KeepFocusWhenInvalid | 在布局容器中使用,容器中的 TextBox 在失去焦点时检查如果数据非法,则保持焦点。 | - ## 2、Controls 该库中定义了一些可能实用的控件。 各控件内部内存泄漏测试情况: - [x] ListBoxEditor - [x] ItemsOperator - [x] PropertyGrid - [x] DragGrid - [x] DocFormatEditor - [x] DragDropHandler - [x] DockLayout ### 2.1、ListBoxEditor 支持分组的列表控件,功能如下图: ![ListBoxEditor](/Images/ListBoxEditor.png) **动图演示:** ![ListBoxEditor](/Images/ListBoxEditor.gif) - [x] 支持分组,多级分组、剔除分组,获取设置的分组字段(AddGroupField、ClearGroupField、GroupFields); - [x] 支持排序,多级排序、剔除排序,获取设置的排序字段(AddSortField、ClearSortField、SortFields); - [x] 支持搜索,搜索结果高亮(SearchString),可选搜索时不过滤(FilterWhenSearch); - [x] 支持自定义过滤事件 (Filter); - [x] 支持在分组栏添加自定义信息(CustomGroupSummary),并且可以设置自定义信息的位置(GroupSummaryTemplate、GroupSummaryLocation); - [x] 支持分组信息模板选择器(GroupSummaryTemplateSelector) - [x] 支持设置分组行背景色、焦点行背景色、鼠标悬停行背景色(GroupBackground、FocusedBrush、MouseOverBrush); - [x] 提供获取分组展开、折叠状态(IsGroupExpanded); - [x] 分组后,支持设置数据行缩进(ItemOffset); - [x] 支持设置用户数据模板(ItemTemplate) - [x] 支持获取分组数量(GroupCount); - [x] 提供控制分组展开、折叠接口(ExpandGroup、CollapseGroup); - [x] 支持根据数据模型跳转到视野中(ScrollIntoView); - [x] 支持获取可见数据模型接口(VisibleItems); - [x] 提供获取焦点行的数据模型接口(FocusedItem); - [x] 页面更新后支持展开状态保持; - [x] 页面更新后支持焦点行保持; - [x] 提供强制刷新接口(RefreshData); - [x] 支持设置数据模型中表示选中的属性,设置后在分组栏、数据行自动显示复选框,复选框状态自动联动(CheckFieldName); 如果希望在分组行添加自定义的数据,需要设置自定义信息的数据模板,即设置 **GroupSummaryTemplate**,同时应该处理 **CustomGroupSummary** 事件,通过事件参数设置用于绑定的属性值,事件参数中可以获取分组的层级 Level,同时可以设置分组的背景色 Background。 ### 2.2、ItemsOperator 该类型通过附加依赖项属性进行使用,用于 ItemsControl 及其子类,功能与 **ListBoxEditor** 类似,提供了分组、排序、过滤、搜索高亮等功能。其中搜索过滤功能,当用在 DataGrid 时需要自行处理过滤事件进行过滤。 **示意图如下:** ![ItemsOperator](/Images/ItemsOperator.png) **动图演示:** ![ItemsOperator](/Images/ItemsOperator.gif) 使用方式可参考如下 xaml ```xaml xmlns:wfs="http://gitee.com/wangfs763/ctrls" ``` ### 2.3、PropertyGrid 功能与 WinForm 中的 PropertyGrid 功能类似,但是数组与列表只能编辑元素,不能添加或删除元素。如果希望对元素进行添加与删除,可以使用自定义编辑器进行编辑。沿用了 WinForm 中 PropertyGrid 方案,即可以使用现有的特性,如 DisplayName、Description。 DragDropHandler ![PropertyGrid](/Images/PropertyGrid.png) **动图演示:** ![PropertyGrid](/Images/PropertyGrid.gif) 提供的接口如下: - [x] 设置编辑对象(SelectedObject) - [x] 支持设置网格线颜色(GridBrush) - [x] 支持设置选中行背景色(SelectedRowBackground) - [x] 支持设置属性区域与属性描述直接按分割条的颜色(RowSplitterBackground) - [x] 支持设置属性名称与属性值之间的分割条的颜色(ColumnSplitterBackground) - [x] 支持分组(EnableGroup) - [x] 支持排序(EnableSort) - [x] 支持枚举值显示自定义文本(在枚举值上使用 Description) - [x] 支持自定义编辑器(在属性或自定义类型上使用 Editor 特性,并实现 PropertyEditor 类) - [x] 支持显示或隐藏描述(ShowDescription) - [x] 支持显示或隐藏分组、排序设置图标(ShowOperationPanel) ### 2.4、DragGrid 一个可以自由拖拽内容位置、宽度、高度(通过权重进行计算)的控件,可以用于排版的编辑。 **界面如下图:** ![DragGrid](/Images/DragGrid.png) **动图演示:** ![DragGrid](/Images/DragGrid.gif) 功能点有如下: - [x] 支持拖拽位置 - [x] 支持调整宽度 - [x] 支持调整高度 - [x] 能够显示拖动模板位置的效果 - [x] 拖动时被拖动的内容支持光标跟随效果 - [x] 可以设置不可改变元素的行 - [x] 可以设置不可拖动到新的行 ### 2.5、DocFormatEditor 一个可以进行文档模板编辑的控件。 **界面如下图:** ![DocFormatEditor](/Images/DocFormatEditor.png) **动图演示:** ![DocFormatEditor](/Images/DocFormatEditor.gif) 功能点有: - [x] 支持多级章节 - [x] 支持不同层级的内容进行拖动调整 - [x] 支持正文内容的拖动调整(使用了 DragGrid) ### 2.6、DragDropHandler 一个可以让 ItemsControl 对象支持拖放的组件。 **动图演示:** ![DragDropHandler](/Images/DragDropHandler.gif) 底下4个是 ListBox。中间2个 ListBox通过数据绑定与上面的 DragGrid 绑定到了同一个数据源。最底下的2个 ListBox 没有使用数据绑定,在 xaml 中给定的数据。 ### 2.7、DockLayout 一个多文档拖拽布局控件,类似 Visual Studio 等软件中,将文档、视图进行自动隐藏、拖拽停靠、拖车主界面等。 **说明**:其中视图窗口的标题右侧部分,及窗口标题右侧的虚线、自动隐藏图标、关闭图标借鉴了开源库 YDock。以及拖动窗口时显示的 Dock 位置图标,即上下左右中等位置图标。 **不同点**:YDock 仿照 VS 的程度更高,视图窗口拖出后会显示在主窗口的上方;文档窗口拖出后,不会一直在上方,即可以被主窗口、视图窗口遮挡。这里的 DockLayout 拖出后的窗口**支持自定义的 Window**,因此,这里不区分视图窗口与文档窗口,视图窗口也不会显示在主窗口的上方。 **界面如下图:** ![DockLayout](/Images/DockLayout.png) **动图演示:** ![DockLayout](/Images/DockLayout.gif) ## 3、ServiceWrapper 该库为系统服务应用程序,在配置文件中可以配置多个需要自启动的控制台程序。 由于系统服务一般以System身份运行,所以运行的控制台程序也同样是以System身份运行。因此,不是可信赖的程序,不建议加到配置中。同时需要知道的时,一般情况下,系统服务无法启动GUI程序。所以,即使启动了带界面的程序也无法看到界面,除非设置服务可以进行用户交互。 安装服务可以使用如下命令: ```shell sc create 想创建的服务名称 binPath= "程序全路径" start= auto DisplayName= "想显示的名称" ``` 配置文件为 WrapperConfig.xml,格式如下: ```xml ``` 部分程序被系统服务运行时,可能不能正确工作,此时设置 Proxy 参数为 true 可能可以解决。