在 ASP.NET 中,富列表控件

分享于 

10分钟阅读

Web开发

  繁體

介绍

本文历史记录我对现有 ASP.NET 列表控件的改进,并且了解自定义Web控件的一些隐秘。

背景

自第一次使用 ASP.NET 框架以来,自定义网页控件一直是我最喜欢的特性之一。 我曾经做过多年的web开发,以及能够将我的逻辑封装到控件中非常吸引人。 在开发自己的控件时,我一直遇到的最大问题是关于一些高级特性的糟糕文档。 我查看了我开发的简单控件,然后我查看了丰富的控件,例如 数据网格 我注意到了巨大的差异。 我发现许多关于自定义网页控件的文章,甚至阅读了这本书。 尽管这些资源很有用,但它们并没有揭示微软网站控件的隐藏秘密。

本文解释了我在开发自己的ASP.NET 列表控件版本时所学到的一些东西。 我找到了各个列表项( 单选钮复选框 ) 要非常丰富,但当放置它们各自的列表控件( RadioButtonListCheckBoxList ) 他们列出了很多功能。 我希望能够自定义各个列表项的样式,并提供工具提示。 不过,我确实喜欢列表控件提供的一些特性,比如数据绑定和布局控制。 当我发现插件的 Lutz反射器时,我决定选择分离微软控件以编写我自己的。

显著的发现

ASP.NET 列表中使用的某些代码被标记为 内部 所以我们低级的非微软开发者没有访问它们的权限。 为此我只是复制了他们的代码 public 有些部分是 public,我从未见过文档。 其中一个类是接口 System.Web.UI.WebControls.IRepeatInfoUser 此类为任何重复的项列表提供布局控件。 界面中最值得注意的部分是:

publicvoid RenderItem(ListItemType itemType, int repeatIndex, 
 RepeatInfo repeatInfo, HtmlTextWriter writer);
为列表中的每个项调用这里代码,以便你可以自己呈现每个项。 下面是在我的RadioList 控件中实现这里方法的完整代码:
publicvoid RenderItem(ListItemType itemType, int repeatIndex, 
 RepeatInfo repeatInfo, HtmlTextWriter writer)
{
 RadioButton button1 = new RadioButton();
 button1.Page = Page;
 button1.GroupName = UniqueID;
 button1.ID = string.Concat(ClientID, "_", 
 repeatIndex.ToString(NumberFormatInfo.InvariantInfo));
 button1.Text = Items[repeatIndex].Text;
 button1.ToolTip = Items[repeatIndex].ToolTip;
 button1.Attributes["value"] = Items[repeatIndex].Value;
 button1.Checked = Items[repeatIndex].Selected;
 button1.TextAlign = TextAlign;
 button1.AutoPostBack = AutoPostBack;
 button1.TabIndex = radioButtonTabIndex;
 button1.Enabled = Enabled;
 foreach(string key in Items[repeatIndex].Attributes.Keys)
 {
 button1.Attributes[key] = Items[repeatIndex].Attributes[key];
 }
 button1.RenderControl(writer);
}
这里代码基本上只是使用来自 Items 集合的信息来构建 单选钮 控件,然后将它的呈现。 就是这么简单 !

RichListItems

我所做的大多数改变都是 System.Web.UI.WebControls.ListItem 我制作了自己的版本 RichListItem 我添加了类型的属性 System.Web.UI.WebControls.TableItemStyle 名名 样式 这允许每个列表项具有自己的样式设置。 当使用设计模式中的控件来保持此类的行为时,这里属性上的属性很重要。

[ Category("Behavior"),
 Description("The Style of this item"),
 DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
 NotifyParentProperty(true),
 PersistenceMode(PersistenceMode.Attribute)]
使用 PersistenceMode.Attribute 将每个列表项的样式信息作为属性( 使用'-'命名约定) 保存。 iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 DesignerSerializationVisibility.Content 是什么让 Visual Studio 将样式保存为内容。

除了向列表项添加样式外,还添加了 工具提示 为了这样做,我必须改变 ViewState 保存的持久性 工具提示 还有 文本 还有 列表项的。

internalobject SaveViewState()
{
 if(misc.Get(TEXTISDIRTY) && misc.Get(VALUEISDIRTY) && misc.Get(TOOLTIPISDIRTY))
 {
 returnnew Triplet(Text, Value, ToolTip);
 }
 elseif (misc.Get(TEXTISDIRTY) && misc.Get(VALUEISDIRTY))
 {
 returnnew Pair(Text, Value);
 }
 elseif (misc.Get(TEXTISDIRTY))
 {
 return Text;
 }
 elseif (misc.Get(VALUEISDIRTY))
 {
 returnnew Pair(null, Value);
 }
 elseif(misc.Get(TOOLTIPISDIRTY))
 {
 returnnew Pair(ToolTip, null);
 }
 returnnull;
}internalvoid LoadViewState(object state)
{
 Pair pair;
 Triplet triplet;
 if (state == null)
 {
 return;
 }
 if ((state as Triplet)!= null)
 {
 triplet = ((Triplet) state);
 Text = (string)triplet.First;
 Value = (string)triplet.Second;
 ToolTip = (string)triplet.Third;
 }
 elseif ((state as Pair)!= null)
 {
 pair = ((Pair) state);
 if (pair.First!= null)
 {
 if(pair.Second!= null)
 Text = (string)pair.First;
 else ToolTip = (string) pair.First;
 }
 if(pair.Second!= null)
 {
 Value = ((string) pair.Second);
 }
 return;
 }
 this.Text = ((string)state);
}
对状态管理的深入解释超出了本文的范围,请注意 LoadViewState 还有 SaveViewState 方法互相依赖。在 RichListItem 中,有三个可以能的值被保持: 文本 , 以及 工具提示

API更改

对于使RichListControls向后兼容 ASP.NET 列表控件,有一些重大的更改。 仍然有一个基类 RichListControl ,它为所有列表控件提供了基础。 我在列表控件和基础之间添加了另一个继承级别 RichListControl 我把它们分成两种不同的类型: SingleSelectListControlMutipleSelectListControl 这允许列表控件只允许选择一个项目来具有 宋体 , 站点地图 , SelectedValue 以及 SelectedText 列出允许多个项被选定的控件具有下列属性 散点图 , 加载宏 , SelectedValues 以及 SelectedTexts 我已经向基础添加了一个属性 RichListControl 名名 HasSelection 指示列表中是否选定了任何项。 下面是这些属性可能使用的示例:

if(list.HasSelection)
{
 foreach(RichListItem item in list.SelectedItems)
 {
 lblSelection.Text += String.Format(" {0}", item.Text);
 }
}else{
 lblSelection.Text = "No Selection";
}

使用代码

RichListControl的使用方式与传统 ASP.NET 列表控件的使用方式完全相同。 请注意下面的StyleToolTip 属性。

<%@RegisterTagPrefix="List"Assembly="RichListControls"Namespace="RichListControls"%><List:RichRadioButtonListid="list"runat="server"><Items><list:RichListItemToolTip="This is not that many miles"Style-Font-Italic="True"Style-ForeColor="Green"Value="0">0 - 15</list:RichListItem><list:RichListItemToolTip="Most People Drive at least this much"Value="5">15 - 30</list:RichListItem><list:RichListItemStyle-Font-Bold="True"Style-ForeColor="Firebrick"Style-BackColor="LightYellow"Value="10">30+</list:RichListItem></Items></List:RichRadioButtonList>

Points of Interest

我使用的helper 类有几个值得注意。 首先,RichDropDownList 使用了 StyleHelper 来转换 System.Web.UI.WebControls.Style 对于可以在HTML样式属性中使用的字符串。 大部分代码是直接从 System.Web dll 中的内部方法获取的。

还有 DataSourceHelper 在数据绑定中使用。 这里代码中的所有代码都来自 System.Web dll。

历史记录

  • 9/9/2004 - 初始版本。

控制  asp  asp-net  lis  列表  Controls  
相关文章