65.9K
CodeProject 正在变化。 阅读更多。
Home

一个简单的 ASP.NET Web 标签页用户控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.94/5 (34投票s)

2004 年 8 月 23 日

CPOL

5分钟阅读

viewsIcon

513624

downloadIcon

14580

为 Web 实现标签页控件。

引言

Windows Forms 的 TabControl 是一个非常有用的控件,用于在同一个屏幕上重叠显示多个 UI。虽然 MSDN 上有作为不受支持的仅 IE 产品提供的 TabStrip Web 控件,以及一些其他基于 ActiveX 的 TabStrip Web 控件,但很难找到任何基于 ASP.NET 的 TabStrip 控件。我在 CodeProject 上找到的唯一文章是 这里。但问题仍然存在:如何定义和实现一个通用且有用的 TabStrip ASP.NET Web 用户控件?本文旨在回答这个问题。

Web TabStrip 可视化设计

本文中的 TabStrip 由一排称为 TabStrip 的命令按钮和一排称为 SubTabStrip 的链接按钮组成。它具有以下视觉属性:

  • TabBackColor/SubTabBackColor - 未选定选项卡或子选项卡的背景颜色。
  • SelectedTabBackColor/SelectedSubTabBackColor - 选定选项卡或子选项卡的背景颜色。
  • TabForeColor/SubTabForeColor - 未选定选项卡或子选项卡的前景色。
  • SelectedTabForeColor/SelectedSubTabForeColor - 选定选项卡或子选项卡的前景色。
  • TabStripBackColor/SubTabStripBackColor - 条的背景颜色。

仔细选择这 10 种颜色属性将呈现出如下所示的 Web 标签页视觉效果:

TabStrip Sample

为了实现这个 Web TabStrip,我创建了一个 ASP.NET 用户控件,其中包含一个两行的 HTML 表,并在每行中插入了一个 Repeater 控件。选项卡/子选项卡的颜色对应于 Repeater<itemTemplate> 中的 <asp:button> 的颜色。选项卡条/子选项卡条的颜色对应于 HTML <td> 的颜色。现在,让我们看看这些颜色如何在用户单击选项卡时正确设置。

Repeater 控件 ItemCommand 事件

当用户单击一个选项卡时,Repeater 会向其处理程序触发一个 ItemCommand 事件。

private void __theTabStrip_ItemCommand(object source, 
                                   RepeaterCommandEventArgs e)
{
    CurrentTabIndex = e.Item.ItemIndex;
    ....
}

基本上,服务器端代码现在可以通过事件参数知道单击了哪个选项卡,并可以相应地进行颜色设置。

<ItemTemplate>
<asp:Button Runat=server .. BackColor="<%# SetTabBackColor(Container) %>" .. />
</ItemTemplate>
protected Color SetTabBackColor(object elem)
  {
    RepeaterItem item = (RepeaterItem) elem;
    if (item.ItemIndex==CurrentTabIndex) return SelectedTabBackColor;
    return TabBackColor;
  }

请注意,ASP.NET 运行时可以像这里看到的一样混合“尖括号”代码和对象代码,特别是使用“<%# #>”将代码绑定函数绑定到标签属性。另外,<asp:button> 位于 <ItemTemplate> 中。因此,“Container”指的是“RepeaterItem”。同样,我们可以编写并绑定颜色设置函数到 ForeColor 以及子选项卡的 Back/ForeColor

您可能已经注意到,我们一直在自由地使用 CurrentSubTabIndexSelectedTabBackColorTabBackColor。这些是 Web 用户控件的状态属性,我们现在将讨论它们。

Web 用户控件状态管理

ASP.NET Web 用户控件允许使用 ViewState 持久化状态,并使用“尖括号”属性初始化状态,这些属性对应于对象属性。

<uc1:TabStrip id="TabStrip1" runat="server" 
                      SelectedTabBackColor="#003333"
                      TabForeColor="Black"
                      TabBackColor="#669999"
                      SelectedTabForeColor="White" 
                      TabStripBackColor="White"  
                      SelectedSubTabBackColor="#003333"
                      SubTabForeColor="Yellow" 
                      SubTabBackColor="#003333"

                      SelectedSubTabForeColor="White" 
                      SubTabStripBackColor="#003333" />

      public Color TabBackColor
      {
         get {return (Color) ViewState["TabBackColor"]; }
         set { ViewState["TabBackColor"]=value;}
      }
      public int CurrentTabIndex
      {
         get {return (int) ViewState["CurrentTabIndex"]; }
      }

ASP.NET 运行时提供的这些出色的基础结构支持使我们能够编写前面部分中的简单颜色更改代码。

警告: ViewState 会占用带宽。因此,您可能需要考虑使用 Session State。

现在我们有了响应用户单击操作的颜色更改的所有代码。那么,我们如何根据用户的单击操作来更改宿主页面的内容呢?

设计 Web TabStrip 事件

显然,这个 TabStrip 不可能预见到宿主页面上的所有内容更改。因此,我决定只引发适当的事件,并将决定如何处理留给用户控件的宿主页面。定义和引发 SelectionChanged 事件的代码如下:

public class SelectionChangedEventArgs : EventArgs
{
   public int TabPosition;
  public int SubTabPosition=0;
}
public delegate void SelectionChangedEventHandler(object sender, 
                                      SelectionChangedEventArgs e);
public event SelectionChangedEventHandler SelectionChanged;

public void SelectTab(int index)
{
   ....
  SelectionChangedEventArgs ev= new SelectionChangedEventArgs();
  ev.TabPosition= index;
  ev.SubTabPosition=(int) ViewState["CurrentSubTabIndex"];
  if( SelectionChanged !=null) SelectionChanged(this,ev);
}

请注意,此函数将在 ItemCommand 事件处理程序函数中调用,以便用户单击操作将触发自定义事件 SelectionChanged

为了在宿主页面上响应这些事件,我们需要在宿主页面上进行以下操作:

TabStrip ts = (TabStrip) this.FindControl("TabStrip1");
....
ts.SelectionChanged+=new SelectionChangedEventHandler(ts_SelectionChanged);

private void ts_SelectionChanged(object sender, 
                   JQD.SelectionChangedEventArgs e)
{
  // your code here
}

在我的事件处理函数中,我设置了一个 IFrame 的源来加载不同的页面。还有许多其他内容更改技术,例如动态加载不同的用户控件或自定义控件、向页面写入文本、更新宿主页面上已有的静态控件。

请注意,IFrame 不是 ASP.NET 服务器控件,因此我无法使用服务器代码更改其属性。相反,我将 Content.aspx 加载到其中,并使用 Session State 更改内容。

关于数据绑定的最后几点

我们已经看到了 <asp:button> 颜色属性如何使用 <%# %> 绑定到代码隐藏函数。我还将其文本绑定到其 Container (Repeater 控件) 的 DataSource,以通过 IList 利用 .NET 运行时数据绑定基础结构。

<TD id="TabStripTD">
    <asp:repeater id=__theTabStrip runat="server" 
         DataSource='<%# DataBinder.Eval(Container,"TabText") %>'>
    <ItemTemplate>
  <asp:Button Runat=server Text="<%# Container.DataItem %>" ... />
....

请注意,<asp:button> 中的“Container”指的是 Repeater 控件,而 <asp:repeater> 中的 Container 指的是 TabStrip 用户控件,该控件有一个可绑定的 ArrayList 属性 TabText

public ArrayList TabText
  {
     get {return _TabText; }
     set { _TabText=value; } 
  }

我选择不持久化 TabText,而是将其留给宿主页面,因为页面是设置它的地方,因此最适合决定何时持久化。

如何在您的 Web 项目中使用 Web TabStrip 用户控件

我包含了一个示例项目,展示了如何使用该控件。如果您需要将此 Web 用户控件包含在您的 Web 应用程序项目中,请执行以下操作:

  1. 在 Solution Explorer 中右键单击您的项目。然后 添加 --> 添加现有项 --> 将文件类型更改为 *.*。然后找到 TabStrip.ascx.ascx.cs.ascx.resx。将这三个文件都包含在您的项目中。
  2. TabStrip.ascx 拖到您的 Web Form 上。然后转到 HTML 视图,为 TabStrip 标签添加“TabBackColor”等属性(请参考我的项目 WebForm1.aspx 或直接从那里复制)。请记住,您可以通过在此设置颜色属性来测试自己的颜色方案。
  3. 在您的 Web Form Page_Load 函数中,设置 TabText ArrayList 来表示显示的选项卡文本列表,并设置 SubTabText HashTable 来表示与每个选项卡对应的子选项卡文本列表。

    您可以考虑使用此行代码访问 TabStrip 用户控件:

    JQD.TabStrip ts = (JQD.TabStrip) this.FindControl("TabStrip1");
  4. 设置用户控件的 SelectionChanged 事件处理程序。
    ts.SelectionChanged += new 
      JQD.TabStrip.SelectionChangedEventHandler(ts_SelectionChanged);

    并在 ts_SelectionChanged 中编写您自己的代码。

请注意,我在 Windows 2003 和 Framework 1.1 上运行了示例,并执行了这些步骤。最后,如果您决定直接运行我的示例,则需要将 zip 文件解压到一个 IIS 虚拟目录“TestTabStrip”中,并在那里打开解决方案,您应该会看到如下屏幕:

Sample screenshot

结论

我向您展示了一个简单通用的 Web TabStrip 用户控件。您也可以将其用作基础模型,添加其他按钮类型(如图像按钮)以满足您的需求。

© . All rights reserved.