这是一个古老的问题,但对于我们这些不幸仍然不得不维护 ASP.NET Web 窗体应用程序的人来说,我在尝试将 Bootstrap 字形包含在内置按钮控件中时自己经历了这个问题。
根据 Bootstrap 文档,所需的标记如下:
<button class="btn btn-default">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
Search
</button>
我需要这个标记由服务器控件呈现,所以我开始寻找选项。
按钮
这将是第一个合乎逻辑的步骤,但是——正如这个问题所解释的—— Button 呈现一个<input>
元素而不是<button>
,因此添加内部 HTML 是不可能的。
来源
<asp:LinkButton runat="server" ID="uxSearch" CssClass="btn btn-default">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
Search
</asp:LinkButton>
输出
<a id="uxSearch" class="btn btn-default" href="javascript:__doPostBack('uxSearch','')">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
Search
</a>
优点
- 看起来不错
Command
事件; CommandName
和CommandArgument
属性
缺点
- 渲染
<a>
而不是<button>
- 呈现并依赖于突兀的 JavaScript
HtmlButton(归功于菲利普的回答)
来源
<button runat="server" id="uxSearch" class="btn btn-default">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
Search
</button>
结果
<button onclick="__doPostBack('uxSearch','')" id="uxSearch" class="btn btn-default">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
Search
</button>
优点
缺点
- 没有
Command
事件;没有CommandName
或CommandArgument
属性
- 呈现并依赖于突兀的 JavaScript 来处理其
ServerClick
事件
在这一点上,显然没有一个内置控件看起来合适,因此下一步合乎逻辑的步骤是尝试修改它们以实现所需的功能。
注意:这是基于 Dan 的代码,所以所有功劳归他所有。
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ModernControls
{
[ParseChildren]
public class ModernButton : Button
{
public new string Text
{
get { return (string)ViewState["NewText"] ?? ""; }
set { ViewState["NewText"] = value; }
}
public string Value
{
get { return base.Text; }
set { base.Text = value; }
}
protected override HtmlTextWriterTag TagKey
{
get { return HtmlTextWriterTag.Button; }
}
protected override void AddParsedSubObject(object obj)
{
var literal = obj as LiteralControl;
if (literal == null) return;
Text = literal.Text;
}
protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write(Text);
}
}
}
我已经将这个类精简到最低限度,并对其进行了重构,以尽可能少的代码实现相同的功能。我还添加了一些改进。即:
- 删除
PersistChildren
属性(似乎没有必要)
- 删除
TagName
覆盖(似乎没有必要)
Text
从(基类已处理此)中删除 HTML 解码
- 保持
OnPreRender
原状;AddParsedSubObject
改为覆盖(更简单)
- 简化
RenderContents
覆盖
- 添加
Value
属性(见下文)
- 添加命名空间(以包含@Register指令的示例)
- 添加必要
using
的指令
该Value
属性只是访问旧Text
属性。value
这是因为本机 Button 控件无论如何都会呈现一个属性(Text
以其值作为其值)。由于value
是<button>
元素的有效属性,因此我决定为其包含一个属性。
来源
<%@ Register TagPrefix="mc" Namespace="ModernControls" %>
<mc:ModernButton runat="server" ID="uxSearch" Value="Foo" CssClass="btn btn-default" >
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
Search
</mc:ModernButton>
输出
<button type="submit" name="uxSearch" value="Foo" id="uxSearch" class="btn btn-default">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
Search
</button>
优点
- 看起来不错
- 渲染一个合适的
<button>
元素
Command
事件; CommandName
和CommandArgument
属性
- 不呈现或依赖于突兀的 JavaScript
缺点