ASP.NET 云控件






4.84/5 (33投票s)
此云控件根据权重以不同的样式显示超链接列表。这类似于 del.icio.us 或 Flickr 中的标签云。
引言
像 del.icio.us、Technorati 和 Flickr 这样的网站允许对其内容进行标记,它们使用标签云来展示标签的流行程度。流行的项目具有更大的字体大小。这个概念可以应用于任何具有关联权重的项目列表。例如,产品列表可以根据产品的成本以云的形式显示。使用本文介绍的 ASP.NET 服务器控件,您可以显示自己特定领域的项目作为云。下图显示了 Ajaxian 文章的示例云。
使用控件
此控件仅与 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
,例如 SqlDataSource
或 AccessDataSource
。
<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 类 Item1
、Item2
...Item7
。如果您不指定 ItemCssClassPrefix
,则字体大小 CSS 属性将根据权重设置,如下所示
标准化权重 | 字体大小 |
---|---|
1 | xx-small |
2 | x-small |
3 | small |
4 | medium |
5 | large |
6 | x-large |
7 | xx-large |
现在,我们来分析一下控件的工作原理。
控件如何工作?
主要逻辑是将权重分布转换为 1 到 7 之间的整数范围。在与统计学斗争了一段时间后,我找到了以下算法来标准化权重
- 计算权重的平均值和标准差 (σ)。这是使用
Statistics
类中的函数完成的,类似于Math
类。 - 权重因子根据以下公式计算
- 标准化权重基于下表获得
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
方法提供。
factor = (weight - mean)/(stddev)
标准化权重 | 条件 |
---|---|
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 日 - 第一个版本。