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

ASP.NET 云控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.84/5 (33投票s)

2006 年 7 月 4 日

CPOL

4分钟阅读

viewsIcon

290712

downloadIcon

1853

此云控件根据权重以不同的样式显示超链接列表。这类似于 del.icio.us 或 Flickr 中的标签云。

引言

del.icio.usTechnoratiFlickr 这样的网站允许对其内容进行标记,它们使用标签云来展示标签的流行程度。流行的项目具有更大的字体大小。这个概念可以应用于任何具有关联权重的项目列表。例如,产品列表可以根据产品的成本以云的形式显示。使用本文介绍的 ASP.NET 服务器控件,您可以显示自己特定领域的项目作为云。下图显示了 Ajaxian 文章的示例云。

sample image

使用控件

此控件仅与 ASP.NET 2.0 一起使用。首先,您需要将控件程序集或控件项目添加到您的网站。在需要使用该控件的页面中,添加以下声明

<%@ Register Namespace="VRK.Controls" TagPrefix="vrk" Assembly="VRK.Controls" %>

这将允许您使用以下声明在页面中使用该控件

<vrk:Cloud ID="c1" runat="server" />

现在,您需要向控件添加项目。每个项目都将显示为页面上的超链接。您可以为要添加的项目提供以下属性

  • Text - 超链接的文本。
  • Href - 用户单击超链接时将导航到的 URL。如果此属性留空,控件将触发回发并引发 ItemClick 事件。
  • Title - HTML anchor 的工具提示文本。
  • Weight - 权重决定了项目的显示方式。

您可以声明式地添加项目,如下所示

<vrk:Cloud ID="c1" runat="server">
<Items>
   <vrk:CloudItem Text="Item1" 
      Href="Default.aspx?tag=Item1" 
      Title="Some title" Weight="4" />
   <vrk:CloudItem Text="Item2" 
      Href="Default.aspx?tag=Item2" 
      Title="Some title" Weight="4" />
</Items>
</vrk:Cloud>

您也可以以编程方式添加项目

c1.Items.Add(new CloudItem("Item1", 4, 
                           "Default.aspx?tag=Item1", 
                           "Some title"
                           ));

您还可以使用数据绑定来添加项目。首先,您需要向页面添加数据源。下面的代码示例显示了一个 ObjectDataSource,但您可以使用任何 ASP.NET DataSourceControl,例如 SqlDataSourceAccessDataSource

<asp:ObjectDataSource 
   ID="ItemsSource" 
   runat="server" 
   SelectMethod="GetItems" 
   TypeName="CloudTest.ItemsSource" 
  />

您需要通过指定 DataSourceID 来指示云控件需要使用 ItemsSource 数据源控件。

<vrk:Cloud ID="c1" runat="server" DataSourceID="ItemsSource" .... />

指定数据源后,您需要指明项目如何从数据源中填充。可以使用以下控件属性来提供信息

  • DataTextField - 绑定到项目 Text 属性的数据字段的名称。
  • DataTextFormatString - Text 属性的格式字符串。字符串中的 {0} 被替换为数据源中字段的值。
  • DataHrefField - 绑定到项目 Href 属性的数据字段。
  • DataHrefFormatString - 用于格式化 Href 属性值的格式字符串。
  • DataTitleField - 绑定到项目 Title 属性的数据字段。
  • DataTitleFormatString - 项目标题(工具提示)的格式字符串。
  • DataWeightField - 数据源中用于获取项目权重的字段。

然后,控件会将所有项目的权重标准化,使其适合 1 到 7 的范围。您可以使用可选的 ItemCssClassPrefix 属性来控制标准化项目的显示。如果您使用 ItemCssClassPrefix 属性,则需要在 HTML 页面中添加七个不同的 CSS 类。例如,如果您将属性值指定为 "Item",则需要指定 CSS 类 Item1Item2...Item7。如果您不指定 ItemCssClassPrefix,则字体大小 CSS 属性将根据权重设置,如下所示

标准化权重 字体大小
1 xx-small
2 x-small
3 small
4 medium
5 large
6 x-large
7 xx-large

现在,我们来分析一下控件的工作原理。

控件如何工作?

主要逻辑是将权重分布转换为 1 到 7 之间的整数范围。在与统计学斗争了一段时间后,我找到了以下算法来标准化权重

  1. 计算权重的平均值和标准差 (σ)。这是使用 Statistics 类中的函数完成的,类似于 Math 类。
  2. private IEnumerable<double> ItemWeights
    {
      get
      {
        foreach (CloudItem item in this.Items)
        {
          yield return item.Weight;
        }
      }
    }
    
    ...
    
    double mean; 
    double stdDev = Statistics.StdDev(ItemWeights, out mean);

    StdDev 函数接受一个 IEnumerable<double> 参数,该参数由 ItemWeights 方法提供。

  3. 权重因子根据以下公式计算
  4. factor = (weight - mean)/(stddev)
  5. 标准化权重基于下表获得
  6. 标准化权重 条件
    1 factor <= -2*stddev
    2 -2*stddev < factor <= -1*stddev
    3 -1*stddev < factor <= -0.5*stddev
    4 -0.5*stddev < factor < 0.5*stddev
    5 0.5*stddev <= factor < 1*stddev
    6 1*stddev < = factor < 2*stddev
    7 factor >= 2 * stddev

获得标准化权重后,设置字体大小和类就很容易了。

foreach (CloudItem item in Items)
{
  HtmlAnchor a = new HtmlAnchor();
  a.HRef = String.IsNullOrEmpty(item.Href) ?
  this.Page.ClientScript.GetPostBackClientHyperlink(this, index.ToString()) :
                   item.Href;
  a.InnerText = item.Text;
  a.Title = item.Title;
  int normalWeight = NormalizeWeight(item.Weight, mean, stdDev);
  if (hasCssClassPrefix)
  {
    a.Attributes["class"] = 
      this.ItemCssClassPrefix + normalWeight.ToString();
  }
  else
  {
    a.Style.Add(HtmlTextWriterStyle.FontSize, _fontSizes[normalWeight - 1]);
  }
  this.Controls.Add(a);
  this.Controls.Add(new LiteralControl(" "));
  index++;
}

该方法在大多数情况下似乎都工作得相当好。欢迎提出任何改进建议。

历史

  • 2006 年 7 月 4 日 - 第一个版本。
© . All rights reserved.