ASP.NET 属性网格用户 Web 控件






4.95/5 (11投票s)
ASP.NET 增强型属性网格控件,可连接到任何类。
引言
ASP.NET 缺少一个基于 WebForm 的属性网格控件,该控件允许直接修改对象,并尊重其组件模型属性。第三方或开源贡献似乎过于笨拙或实现不佳。在最近开发自定义框架时,我发现自己需要为许多 ASP.NET 网页配置,这些网页会操作我的业务对象。我没有太多时间手动创建这些页面来适应我的业务对象的独特需求,因此我选择花费几个小时编写一个 ASP.NET 基于 Web 的属性网格类型的用户控件。我主要希望用户控件能够动态地检查单个对象,构建必要的 HTML 输入标签来读取和操作类的公共属性。此控件并非完美,仍有很大的改进空间。
详细说明
好的,首先:此用户控件如何加快网页开发速度? 通常,构建收集用户输入并将其应用于后端数据库的网页非常耗时。标签、各种输入控件、格式化、条件显示或读/写行为等都需要时间来实现。而且,各种 CRUDL([C]reate [R]ead [U]pdate [D]elete [L]ist)功能可能跨越多个页面,或者在某些不幸的情况下,可能全部挤在一个过于复杂的网页中。我们通常需要做很多繁琐的工作才能从数据库读取数据、将新数据推送到数据库或更新数据库中的现有数据。此外,如果对象发生更改,调用该对象的网页也必须更改。我坚信将数据库 select 语句和存储过程调用排除在用户界面标记之外,而是使用中间层(业务对象)来处理数据库活动。对象 Web 编辑器能够检查已调用的类,读取其组件模型属性,动态地呈现属性的名称以及最合适的输入用户控件,以及收集和应用 PostBack 数据到对象以供进一步处理。这大大减少了所需的 HTML 表单工作量,从而可以快速实现网页。此外,此用户控件的一个令人愉悦的副作用是页面实现一致。
Microsoft 的 System.ComponentModel
命名空间提供了一种标记类的方式,通过这种方式,对象元数据将包含设计时/运行时“规则”,用于与给定类的对象实例进行交互。对象 Web 编辑器的核心是其递归反射到对象实例的能力,读取每个属性,检测其数据类型,并根据属性设计器属性提供正确的访问权限。
让我们来看看这个用户控件在网页上的使用方式以及它在页面加载时所做的事情。下面是一个简单网页的截图,该网页在其代码隐藏中调用了一个 Person
类。
在这里,我们看到左侧是由对象 Web 编辑器动态创建的 HTML 渲染,右侧是 ASP.NET 网页及其代码隐藏的设计时视图。我选择不花太多时间在这个用户控件的设计时渲染和编辑方面,所以没有设计时渲染的 HTML 或相关的属性编辑器。网页在其标记中定义了以下内容...
<owe:ObjectWebEditor
id="personEditor"
runat="server"
ViewStateMode ="Enabled"
HiddenProperties="Exceptions" >
<owe:PropertyMap
PropertyName="HomePage"
LinkDescription="My Home Page"
URL="MyHomePage.aspx?SSN={SSN}"
ToolTip="Visit my Home Page" />
</owe:ObjectWebEditor>
我将介绍这个自定义用户控件中不那么明显的属性。
HiddenProperties
– 此字符串包含一个逗号分隔的属性列表,您不希望显示这些属性。“显示”意味着动态生成 HTML 以允许查看和可能编辑这些属性。在上面的示例中,我已经排除了底层 Person
类的 Exceptions
属性。在 ObjectWebEditor
用户控件中定义的子控件为某些属性提供了自定义处理。在下面的示例中,我选择用一个名为“My Home Page”的超链接替换“HomePage
”属性通常渲染的 HTML。
Default.aspx 调用 Person
类的实例,并且 ObjectWebEditor
用户控件的 SelectedObject
属性设置为该实例。在 Page Load 时,ObjectWebEditor
检查 Person
对象,渲染显示其属性所需的 HTML。编辑器会遵循 ReadOnly
等组件模型属性,并且仅为公共成员生成 HTML。
类属性的 Category
属性用作章节标题。这些属性会按照在对象检查过程中遇到的顺序进行渲染。
可以通过在 ObjectWebEditor
的 HiddenCategories
属性中定义类别名称来隐藏整个类别,这与隐藏属性类似。
请注意下面的某些 HTML 输入字段是灰色的。这是因为这些属性在 Activity 类级别被标记为只读。但这并不意味着不能以编程方式更改它们。
HTML 标记是由 Object Web Editor 用户控件自动即时生成的。每个 HTML 输入字段的命名方式都可以让 Object Web Editor 用户控件在 Post Back 发生时确定将提交的值应用于何处。包含 Description
属性 HTML 标记的表格行如下所示。
<tr
class="PropertyGridPropertyRow"
align="left">
<td
class="PropertyGridPropertyName"
valign="top"
align="left"
width="100%">Age</td>
<td
class="PropertyGridPropertyValue"
valign="top"
align="left"
width="100%">
<input
id="personEditor_2"
name="personEditor_2"
type="Text"
value="52" >
</td>
</tr>
每个 HTML 输入字段的名称结合了 Object Web Editor 控件的名称加上所表示属性的计数。这确保了无论页面上存在多少个此类控件,每个 HTML 输入字段都是唯一的。
在 post back 时,ObjectWebEditor
访问 Request Form 字段集合,并将文件名与其内部的表单字段名到 Selected Object 类属性的映射进行匹配。它应该能够做到这一点。毕竟,它首先创建了这些字段;o)
某些类可能包含其他类的实例作为公共属性。ObjectWedEditor
通过调用自身的新实例并将其附加到属性来处理此问题……有效地成为其编辑器。即使如此,这个新用户控件实例的 ClientID 也通过结合其父“编辑器”的 ClientID 和“X”来使其唯一,结果是“editorX”。如果假设的子类还有另一个子类,同样的操作会再次进行,结果是“editorXX”等等。
在某些情况下,您可能希望隐藏一个或多个属性的即时生成的 HTML 标记。这可以通过 Object Web Editor 用户控件的 HiddenProperies
属性来实现。
HiddenProperties="Exceptions,ActivityStatus,ActivityType,Prerequisites"
类类别也同样如此。
HiddenCategories="System"
在某些情况下,给定属性的实际名称不适合用户界面显示。在下面的示例中,我们使用嵌套的 PropertyMap
定义将“LastName”显示的标签更改为“Persons Last Name”。
JavaScript 可以放在 PropertyMap
定义的 URL 属性中,以便触发其他动态运行时行为。
PropertyMap
控件还可以用 Selected Object 的命名属性值替换令牌化的值。这里我们看到 Person.SSN
被应用于一个 URL…
Object Web Editor 用户控件生成的每个 HTML 表元素都可以按如下方式进行样式设置
.PropertyGrid
{
}
.PropertyNestedGrid
{
}
.PropertyGridCategory
{
white-space: nowrap;
}
.PropertyGridCategoryName
{
white-space: nowrap;
font-weight: bold;
}
.PropertyGridPropertyRow
{
white-space: nowrap;
}
.PropertyGridPropertyName
{
white-space: nowrap;
}
.PropertyGridPropertyValue
{
white-space: nowrap;
}
.PropertyGridPropertyLink
{
white-space: nowrap;
}
对我而言,ObjectWebEditor
用户控件通过为我现在处理的很大一部分页面提供动态生成的表示和数据收集 HTML,极大地缩短了 ASP.NET 网页开发时间。使用此控件,我能够在大约半小时内快速完成 20 个封装业务对象的网页,而不是花一天时间手动构建它们。此外,这些页面在 ASP 标记和代码隐藏方面看起来都非常统一。
历史
- 1/2/2012:初始发布。