TitleCheckBoxList向CheckBoxList控件添加列标题/标题

分享于 

13分钟阅读

Web开发

  繁體

屏幕截图- titlecheckboxlist1.gif

介绍

设计 TitleCheckBoxList 控件是为了允许你将列标题/标题插入到 CheckBoxList 中。 标题包含在 ListControlItems 集合中,但不在窗体上呈现 CheckBox

如果你要在复选框的List 中显示许多选项,并且要根据所表示的类型或者类别来组织复选框。

使用控件

App_Code 文件夹中添加 TitleCheckBoxList.cs 类文件到你的项目。

你可以通过点击本文顶部的'下载源代码'链接来下载这个 C# 类文件。

using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.IO;namespace VwdCms
{
 publicclass TitleCheckBoxList : CheckBoxList
 {
 publicconststring TitleValue = "###title###";
 publicconststring SpacerValue = "###spacer###";
 private Unit _titleWidth;
 public Unit TitleWidth
 {
 get { return _titleWidth; }
 set { _titleWidth = value; }
 }
 protectedoverridevoid RenderItem(ListItemType itemType, 
 int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
 {
 ListItem itm = this.Items[repeatIndex];
 string val = itm.Value;
 if (val == TitleValue || val == SpacerValue )
 {
 if (repeatIndex == 0)
 {
 StringWriter sw = new StringWriter();
 HtmlTextWriter dummyWriter = new HtmlTextWriter(sw);
 base.RenderItem(itemType, repeatIndex, 
 repeatInfo, dummyWriter);
 }
 if (val == TitleValue)
 {
 Label lbl = new Label();
 lbl.Font.CopyFrom(this.Font);
 lbl.Font.Bold = true;
 lbl.Text = itm.Text;
 if (this.TitleWidth!= null)
 {
 lbl.Width = this.TitleWidth;
 }
 lbl.RenderControl(writer);
 }
 elseif (val == SpacerValue)
 {
 writer.Write(HtmlTextWriter.SpaceChar);
 }
 }
 else {
 base.RenderItem(itemType, repeatIndex, repeatInfo, writer);
 }
 }
 }
}

步骤 2: 更新你的web.config 文件节( 在 system.web 部分)的Controls:

<pages><controls><addtagPrefix="VwdCms"namespace="VwdCms"/> 
 </controls></pages>

步骤 3:TitleCheckBoxList 控件添加到你的Web窗体中:

<VwdCms:TitleCheckBoxList runat="server" ID="cblTitles" RepeatDirection="Vertical" RepeatColumns="5" 
 style="font-family:Arial;font-size:8pt;text-align:left;
 border:solid 1px #336699;" TitleWidth="90px"/>

一些例子

你可以通过单击本文顶部的'下载演示'链接来下载这些示例的代码。

示例 1

这个例子演示了当所有的列都具有相同的条目数时 TitleCheckBoxList 将如何呈现。

,advance,set,clean,clean,clean,Since,Since,Since,Since,Since,Since,Since,Since,Since,Since,Since,Since,Since等。

通过设置 TitleCheckBoxListTitleWidth 属性,可以在不使用 CheckBoxListRepeatLayout的情况下获得列之间的间距。

。titlecheckboxlist在每列的顶部显示标题

下面是加载这里 TitleCheckBoxList的代码:

if (!this.Page.IsPostBack)
{
 // if this is the initial load (HTTP GET) of the page // then put some items in the checkboxlistint catNum = 0;
 int itmNum = 0;
 int i = 0;
 ListItem itm = null;
 for (catNum = 0; catNum <5; catNum++)
 {
 itm = new ListItem("Category" + catNum.ToString(),
 VwdCms.TitleCheckBoxList.TitleValue);
 this.cblTitles.Items.Add(itm);
 itmNum++;
 for (i = 0; i <6; i++)
 {
 itm = new ListItem("Item" + itmNum.ToString(), 
 itmNum.ToString());
 // select the even ones itm.Selected = (itmNum % 2 == 0);
 this.cblTitles.Items.Add(itm);
 itmNum++;
 }
 }
}

示例 2

这个例子演示了当每个类别中的条目数不同时,TitleCheckBoxList 将如何呈现。

对于某些应用程序,这可以能是可以接受的;对于它的他人来说,可以能需要使显示器更清晰。 查看示例 3以查看如何清理显示。

。titlecheckboxlist在每列的顶部显示标题

下面是加载这里 TitleCheckBoxList的代码:

if (!this.Page.IsPostBack)
{
 // if this is the initial load (HTTP GET) of the page // then put some items in the checkboxlist// this example demonstates how the TitleCheckBoxList will // render when the nubmer of items under // each category is differentint catNum = 0;
 int itmNum = 0;
 int i = 0;
 int itemCount = 6;
 ListItem itm = null;
 for (catNum = 0; catNum <5; catNum++)
 {
 itm = new ListItem("Category" + catNum.ToString(),
 VwdCms.TitleCheckBoxList.TitleValue);
 this.cblTitles.Items.Add(itm);
 itmNum++;
 for (i = 0; i < itemCount; i++)
 {
 itm = new ListItem("Item" + itmNum.ToString(), 
 itmNum.ToString());
 // select the even ones itm.Selected = (itmNum % 2 == 0);
 this.cblTitles.Items.Add(itm);
 itmNum++;
 }
 itemCount--;
 }
}

示例 3

本示例演示如何在每个类别中的项数不同时呈现 TitleCheckBoxList,但是可以通过添加"间隔符" ListItem s。

。titlecheckboxlist在每列的顶部显示标题

下面是加载这里 TitleCheckBoxList的代码:

if (!this.Page.IsPostBack)
{
 // if this is the initial load (HTTP GET) of the page // then put some items in the checkboxlist// this example demonstates how the TitleCheckBoxList will // render when the nubmer of items under // each category is differentint catNum = 0;
 int itmNum = 0;
 int i = 0;
 int itemCount = 6;
 // getting the itemCountMax in a real world application will be// more challenging, you may have to loop through the collection// once before looping through and adding list items.int itemCountMax = 6;
 ListItem itm = null;
 for (catNum = 0; catNum <5; catNum++)
 {
 itm = new ListItem("Category" + catNum.ToString(),
 VwdCms.TitleCheckBoxList.TitleValue);
 this.cblTitles.Items.Add(itm);
 itmNum++;
 for (i = 0; i < itemCountMax; i++)
 {
 if (i > itemCount - 1)
 {
 // add a spacer  itm = new ListItem(string.Empty, 
 VwdCms.TitleCheckBoxList.SpacerValue);
 }
 else {
 itm = new ListItem("Item" + itmNum.ToString(), 
 itmNum.ToString());
 // select the even ones itm.Selected = (itmNum % 2 == 0);
 }
 this.cblTitles.Items.Add(itm);
 itmNum++;
 }
 itemCount--;
 }
}

处理回发

在 postback 处理过程中,你需要在使用 TitleCheckBoxList 时需要注意的细微差异。 底层 CheckBoxList 认为 Items 集合中的所有 ListItem 都是有效的CheckBox 控件。 实际上,它们是有效的ListItem,但是 TitleCheckBoxListRenderItem 方法防止为标题和间隔项呈现 CheckBox 控件。

结果是,在循环访问 Items 集合时,代码需要检查标题和间隔,以确定选中哪些项。

下面是一些示例代码:

void btnPostback_Command(object sender, CommandEventArgs e)
{
 // loop through the items and add the selected ones // to the"selected" label control and add the // non-selected ones to the"non-selected" label// Note: the CheckBoxList control thinks that the // Title items and Spacer items are valid ListItems, // but we want to ignore them when looping through // the collection StringBuilder sbSelected = new StringBuilder();
 StringBuilder sbNonSelected = new StringBuilder();
 foreach (ListItem itm inthis.cblTitles.Items)
 {
 if (itm.Value!= VwdCms.TitleCheckBoxList.TitleValue 
 && itm.Value!= VwdCms.TitleCheckBoxList.SpacerValue )
 {
 if (itm.Selected)
 {
 sbSelected.Append(itm.Text);
 sbSelected.Append(",");
 }
 else {
 sbNonSelected.Append(itm.Text);
 sbNonSelected.Append(",");
 }
 }
 }
 this.lblSelected.Text = sbSelected.ToString();
 this.lblNonSelected.Text = sbNonSelected.ToString();
}

Points of Interest

dummyWriter在TitleCheckBoxList的RenderItem方法中做了什么?

当我尝试使用重写的RenderItem 方法时遇到了一个奇怪的问题- TitleCheckBoxList 中的所有复选框都被禁用了。 当我尝试没有任何标题 ListItem的时候,复选框被启用。 经过几分钟的实验,我发现只有当第一个 ListItem 是标题时才会出现。 很明显,基类 CheckBoxListRenderItem 方法在第一个 ListItem 呈现时执行某些操作,如果不使用第一个 ListItemRenderItem,所有复选框将被禁用。

我查看了 CheckBoxList 类文档,无法找到控制这种行为的任何方法。 尽管如这里,尽管我真的不想使用 CheckBoxListRenderItem,但是我需要在第一个 ListItem 中调用。 我希望偶尔重写行为以呈现标题,但否则使用基类实现来呈现复选框。 我认为这个问题是 CheckBoxList 类中的一个 Bug,因为如果类真的是虚拟的,那么不应该使用基方法。 我没有bothered向微软报告这个问题- feel请让他们知道 !

最简单的解决方案是执行基类 RenderItem 方法,但不要让它将任何HTML输出到Web表单。 这是 dummyWriter 进行播放的地方;基类在第一个 ListItem 上执行它的工作并将HTML输出到从未使用过的dummyWriter

再来一次。

水平渲染

目前,TitleCheckBoxList 完成我需要的工作,所以我没有添加任何它的他功能或者在输出中尝试它的他变体。 当然,你的需求会有所变化,你应该更自由地尝试。 也许你希望在行而不是列中呈现复选框,这似乎不太难完成。 我将通过将 RepeatDirection 设置为" Horizontal",然后将 RepeatColumns 属性设置为要在行中显示的最大 ListItem 数量。 在加载 TitleCheckBoxList 时可能会有一些复杂的代码,以便在正确的位置插入间隔和行标题。

将其他控件或者内容插入 CheckBoxList

为什么我们不能将其他类型的控件插入到 CheckBoxList 中? 我需要在 CheckBoxList 中获得一个标题,但也许你需要插入 Button 或者 Image。 能做到绝对可以? ! 如果遵循如何在方法的TitleCheckBoxListRenderItem 中呈现 Label 控件,可以基本呈现任何类型的控件来代替 ListItem

结束语

.NET 框架和 ASP.NET 使修改和扩展类和控件的功能变得非常容易。 你所需要的只是知道框架如何构建和组件互相交互的方式。

通过使用少于 70行代码扩展 CheckBoxList 类,我能够获得我寻找的精确功能。 所以,如果内置控件不做你想要的,不要放弃,改变他们工作的方式更好。


控制  COL  添加  HEAD  column  Header  
相关文章