在Blazor中构建数据库应用程序——第4部分——UI控件
目录
介绍
存储库和数据库
组件
RouteViews
表单
UI控件
UIBase
一些例子
UIButton
UIColumn
UILoader
UIContainer/UIRow/UIColumn
总结
介绍
本文是构建Blazor数据库应用程序系列文章中的第四篇。本文着眼于我们在UI中使用的组件,然后重点介绍如何从HTML和CSS构建通用UI组件。
- 项目结构和框架——一些介绍。
- 服务——构建CRUD数据层。
- 查看组件——UI中的CRUD编辑和查看操作。
- UI组件——构建 HTML/CSS控件。
- 查看组件——UI中的CRUD列表操作。
存储库和数据库
文章的存储库已移至CEC.Blazor.SPA存储库。 CEC.Blazor GitHub存储库已过时,将被删除。
存储库中的/SQL中有一个用于构建数据库的SQL脚本。
您可以在同一站点上看到在此处运行的项目的Server和WASM版本。
组件
要详细了解组件,请阅读我的文章深入了解 Blazor 组件。
Blazor UI中的所有内容(起始页除外)都是一个组件。是的,应用程序、路由器……它们都是组件。并非所有组件都发出Html。
您可以将组件分为四类:
- RouteViews ——这些是顶级组件。视图与布局相结合以形成显示窗口。
- Layouts——布局与视图结合构成显示窗口。
- Forms——表单是控件的逻辑集合。编辑表单、显示表单、列表表单、数据录入向导都是经典的表单。表单包含控件——不是HTML。
- Controls——控件要么显示某些内容——发出 HTML——要么执行某些工作单元。文本框、下拉菜单、按钮、网格都是经典的Hrtml发射控件。应用程序、路由器、验证是执行工作单元的控件。
RouteViews
RouteViews是特定于应用程序的,RouteView和Form之间的唯一区别是RouteView通过@Page指令声明一个或多个路由。在根App中声明的Router组件将设置为一个特定的代码程序集AppAssembly。这是Router在启动时搜索所有声明路由的程序集。
在应用程序中,RouteViews被声明在WASM应用程序库中。
天气预报查看器和列表视图如下所示。
// Blazor.Database/RouteViews/Weather/WeatherViewer.cs
@page "/weather/view/{ID:int}"<WeatherForecastViewerForm ID="this.ID" ExitAction="this.ExitToList"></WeatherForecastViewerForm>@code {[Parameter] public int ID { get; set; }[Inject] public NavigationManager NavManager { get; set; }private void ExitToList()=> this.NavManager.NavigateTo("/fetchdata");
}
// Blazor.Database/RouteViews/Weather/FetchData.cs
@page "/fetchdata"<WeatherForecastComponent></WeatherForecastComponent>
表单
我们在上一篇文章中看到了表单。它们特定于应用程序。
下面的代码显示了天气查看器。都是UI控件,没有HTML标记。
// Blazor.Database/Components/Forms/WeatherForecastViewerForm.razor
@namespace Blazor.Database.Components
@inherits RecordFormBase<WeatherForecast><UIContainer><UIFormRow><UIColumn><h2>Weather Forecast Viewer</h2></UIColumn></UIFormRow>
</UIContainer>
<UILoader Loaded="this.IsLoaded"><UIContainer><UIFormRow><UILabelColumn>Date</UILabelColumn><UIInputColumn Cols="3"><InputReadOnlyText Value="@this.ControllerService.Record.Date.ToShortDateString()"></InputReadOnlyText></UIInputColumn><UIColumn Cols="7"></UIColumn></UIFormRow><UIFormRow><UILabelColumn>Temperature °C</UILabelColumn><UIInputColumn Cols="2"><InputReadOnlyText Value="@this.ControllerService.Record.TemperatureC.ToString()"></InputReadOnlyText></UIInputColumn><UIColumn Cols="8"></UIColumn></UIFormRow><UIFormRow><UILabelColumn>Temperature °f</UILabelColumn><UIInputColumn Cols="2"><InputReadOnlyText Value="@this.ControllerService.Record.TemperatureF.ToString()"></InputReadOnlyText></UIInputColumn><UIColumn Cols="8"></UIColumn></UIFormRow><UIFormRow><UILabelColumn>Summary</UILabelColumn><UIInputColumn Cols="9"><InputReadOnlyText Value="@this.ControllerService.Record.Summary"></InputReadOnlyText></UIInputColumn></UIFormRow></UIContainer>
</UILoader>
<UIContainer><UIFormRow><UIButtonColumn><UIButton AdditionalClasses="btn-secondary" ClickEvent="this.Exit">Exit</UIButton></UIButtonColumn></UIFormRow>
</UIContainer>
页面背后的代码相对简单——复杂的是父类中的样板代码。它加载记录特定的控制器服务。
// Blazor.Database/Components/Forms/WeatherForecastViewerForm.razor.cs
public partial class WeatherForecastViewerForm : RecordFormBase<WeatherForecast>
{[Inject] private WeatherForecastControllerService ControllerService { get; set; }protected async override Task OnInitializedAsync(){this.Service = this.ControllerService;await base.OnInitializedAsync();}
}
UI控件
UI控件发出HTML和CSS标记。这里的所有控件都基于Bootstrap CSS框架。所有控件都继承自ComponentBase,UI控件继承自UIBase。
UIBase
UIBase继承自Component 。它构建了一个可以打开或关闭的HTML DIV块。
让我们详细看一些UIBase。
可以使用Tag参数设置HTML块标记。它只能由继承的类设置。
protected virtual string HtmlTag => "div";
控件CSS类是使用CssBuilder类构建的。继承类可以设置一个主要的Css值并添加他们想要的任意数量的次要值。添加CSS类可以通过AdditionalClasses参数或通过定义class属性来添加。
[Parameter] public virtual string AdditionalClasses { get; set; } = string.Empty;
protected virtual string PrimaryClass => string.Empty;
protected List<string> SecondaryClass { get; private set; } = new List<string>();protected string CssClass
=> CSSBuilder.Class(this.PrimaryClass).AddClass(SecondaryClass).AddClass(AdditionalClasses).AddClassFromAttributes(this.UserAttributes).Build();
可以使用两个参数隐藏或禁用该控件。当Show为真时显示ChildContent。如果Show是假则显示HideContent,如果它不是null,否则什么也不显示。
[Parameter] public bool Show { get; set; } = true;
[Parameter] public bool Disabled { get; set; } = false;
[Parameter] public RenderFragment ChildContent { get; set; }
[Parameter] public RenderFragment HideContent { get; set; }
最后,控件捕获任何附加属性并将它们添加到标记元素中。
[Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary<string, object> UserAttributes { get; set; } = new Dictionary<string, object>();
该控件构建输入RenderTree代码。
protected override void BuildRenderTree(RenderTreeBuilder builder)
{if (this.Show){builder.OpenElement(0, this.HtmlTag);if (!string.IsNullOrWhiteSpace(this.CssClass)) builder.AddAttribute(1, "class", this.CssClass);if (Disabled) builder.AddAttribute(2, "disabled");builder.AddMultipleAttributes(3, this.UserAttributes);if (this.ChildContent != null) builder.AddContent(4, ChildContent);else if (this.HideContent != null) builder.AddContent(5, HideContent);builder.CloseElement();}
}
一些例子
本文的其余部分将更详细地介绍一些UI控件。
UIButton
这是一个标准的Bootstrap按钮。
- Type设置按钮类型。
- PrimaryClass 设置。
- ButtonClick 处理按钮单击事件并调用EventCallback。
- Show和Disabled处理按钮状态。
// Blazor.SPA/Components/UIComponents/Base/UIButtons.cs
@namespace Blazor.SPA.Components
@inherits UIBase
@if (this.Show)
{<button class="@this.CssClass" @onclick="ButtonClick" type="@Type" disabled="@this.Disabled" @attributes="UserAttributes">@this.ChildContent</button>
}
@code {[Parameter] public string Type { get; set; } = "button";[Parameter] public EventCallback<MouseEventArgs> ClickEvent { get; set; }protected override string PrimaryClass => "btn mr-1";protected async Task ButtonClick(MouseEventArgs e) => await this.ClickEvent.InvokeAsync(e);
}
下面是一些显示正在使用的控件的代码。
<UIButton Show="true" Disabled="this._dirtyExit" AdditionalClasses="btn-dark" ClickEvent="() => this.Exit()">Exit</UIButton>
UIColumn
这是一个标准的Bootstrap列。
- Cols 定义列数
- PrimaryCss是从Cols构建的。
- Base RenderTreeBuilder将控件构建为div。
// Blazor.SPA/Components/UIControls/Base/UIColumn.cs
public class UIColumn : UIBase
{[Parameter] public virtual int Cols { get; set; } = 0;protected override string PrimaryClass => this.Cols > 0 ? $"col-{this.Cols}" : $"col";
}
UILoader
这是一个包装控件,旨在保存在子内容中实现错误检查。它仅在IsLoaded为 true时呈现其子内容。该控件节省了在子内容中实现大量错误检查。
@namespace Blazor.SPA.Components
@inherits UIBase@if (this.Loaded)
{@this.ChildContent
}
else
{<div>Loading....</div>
}@code {[Parameter] public bool Loaded { get; set; }
}
您可以在“编辑”和“查看”表单中看到正在使用的控件。
UIContainer/UIRow/UIColumn
这些控件通过使用正确的Css构建DIV来创建BootStrap网格系统——即容器、行和列。
public class UIContainer : UIBase
{protected override string PrimaryClass => "container-fluid";
}
class UIRow : UIBase
{protected override string PrimaryClass => "row";
}
public class UIColumn : UIBase
{[Parameter] public virtual int Cols { get; set; } = 0;protected override string PrimaryClass => this.Cols > 0 ? $"col-{this.Cols}" : $"col";
}
// CEC.Blazor/Components/UIControls/UIBootstrapContainer/UILabelColumn.cs
public class UILabelColumn : UIColumn
{protected override string _BaseCss => $"col-{Columns} col-form-label";
}
下面是一些显示正在使用的控件的代码。
<UIContainer><UIRow><UILabelColumn Columns="2">Date</UILabelColumn>............</UIRow>
..........
</UIContainer>
总结
本文概述了如何使用组件构建UI控件,并详细研究了一些示例组件。你可以在GitHub Repository中看到所有的库UIControls
需要注意的一些关键点:
- UI控件使您可以从更高级别的组件(例如表单和视图)中抽象标记。
- UI控件为您提供控制权,并对HTML和CSS标记应用一些规则。
- View和Form组件更清晰、更易于查看。
- 使用尽可能少或尽可能多的抽象。
- 控件,例如UILoader,让生活更轻松!
如果您在未来阅读本文,请查看存储库中的自述文件以获取文章集的最新版本。
https://www.codeproject.com/Articles/5280090/Building-a-Database-Application-in-Blazor-Part-4-U
在Blazor中构建数据库应用程序——第4部分——UI控件相关推荐
- 在Blazor中构建数据库应用程序——第3部分——UI中的CRUD编辑和查看操作
目录 介绍 示例项目.代码和链接 基本表单 RecordFormBase EditRecordFormBase 实现表单 WeatherForecastViewerForm WeatherForeca ...
- 在Blazor中构建数据库应用程序——第6部分——向天气应用程序添加新记录类型及其UI
目录 介绍 示例项目和代码 过程概述 数据库 CEC天气库 为记录添加模型类 添加一些实用程序类 更新WeatherForecastDbContext 添加数据和控制器服务 表单 WeatherSta ...
- 在Blazor中构建数据库应用程序——第5部分——查看组件——UI中的CRUD列表操作
目录 介绍 存储库和数据库 列表功能 基本表单 分页和排序 分页器 分页器数据 分页器控件 排序控件 UIDataTableHeaderColumn 天气预报列表表单 视图 WeatherForeca ...
- 在Blazor中构建数据库应用程序——第1部分——项目结构和框架
目录 介绍 存储库和数据库 设计理念 数据 UI 解决方案结构 界面结构 页面 路由视图 布局 表单 控件 Blazor.Database项目 Program.cs ServiceCollection ...
- 在Blazor中构建数据库应用程序——第2部分——服务——构建CRUD数据层
目录 存储库和数据库 目标 服务 泛型 数据访问 DbTaskResult 数据类 WeatherForecast 实体框架层 WeatherForecastDBContext LocalWeathe ...
- 在 Visual Basic 6 中让用户在运行时移动和调整控件大小
标题 在 Visual Basic 6 中让用户在运行时移动和调整控件大小 描述 此示例说明如何让用户在 Visual Basic 6 中在运行时移动控件和调整控件大小. 关键词 拖动.移动.调整 ...
- delphi控件切图界面闪烁_小程序设计,不得不说的7个坑 (附资源:新版小程序 UI 控件,Sketch 版)...
一年半的时间,我们亲眼见证了小程序从萌芽成长为参天大树,支撑起我们现今的生活方式,让我们在他的树荫下享受着舒适.很多公司自然不会错过这次机会,纷纷加入到小程序的行列. 这对设计和开发而言算是一次挑战, ...
- android通过代码设置铃声_第六十四回:Android中UI控件之SeekBar
各位看官们,大家好,上一回中咱们说的是Android中UI控件之ProgressBar的例子,这一回咱们的例子是UI控件之SeekBar.闲话休提,言归正转.让我们一起Talk Android吧! 看 ...
- android listview 滑动条显示_第七十六回:Android中UI控件之RecyclerView基础
各位看官们,大家好,上一回中咱们说的是Android中UI控件之ListView优化的例子,这一回咱们说的例子是UI控件之RecyclerView.闲话休提,言归正转.让我们一起Talk Androi ...
最新文章
- Python开发【第三篇】:文件操作与函数
- 如何利用SEO做好网站推广
- 在阿里写了8年代码后,我才明白这些道理
- List, Stack, and Queue
- 打开电脑的组策略编辑器-计算机配置→管理模板下怎么没有网络,我应该怎么做才能通过FireWire卡屏幕播放?...
- python单片机编程软件下载_Python开发例程大全
- [ZJOI2012]灾难(建图)
- jdbc executebatch 非事务_面试:Mybatis事务请讲解一下?
- 高端存储器研发再获突破 集成电路国产化进程加快
- 【收藏】2004年最值得推荐的管理类书籍
- 汇编语言教程 -- 寄存器
- 自控力:和压力做朋友(斯坦福大学实用的心理学课程) 读后感
- 视频教程-物联网嵌入式技术应用-物联网技术
- shipyard安装不迷茫
- 【Bash百宝箱】shell内建命令之builtin、command、caller
- mybatis中sql语句中大于小于号的两种解决方法
- 高炉煤气净化提质技术及发展趋势浅谈
- 成都榆熙:举报评价一般几个工作日被审核?
- 19.0~19.11 Dates, Calendars, and Events 日历事件的处理
- 行为研究:用户行为背后的意义和4点价值
热门文章
- ros发布节点信息python_ROS入门笔记(一): ROS简介
- 大数据数据收集数据困难_工厂质量成本数据收集流程、方案
- html 展示 python结果_在HTML中显示Python值
- java字节流复制_Java使用字节流复制文件的方法
- layui时间选择30分钟为单位_如何集中注意力,不妨试试番茄工作法 | 五色时间管理法...
- 字体设计灵感合集|字体决定了设计
- (秋季)秋天海报设计素材模板
- git依赖python_python爬虫之git的安装
- python作用域顺序排列_详解Python函数作用域的LEGB顺序
- C++设计模式详解之装饰者模式解析