我想在ASP.NET网站中使用较新的<button>标记,其中包括允许CSS样式的文本和在按钮内嵌入图形.asp:Button控件呈现为<input type="button">,有没有办法使先前存在的控件呈现为<button>

从我所读到的内容来看,当按钮位于<form>以内,但在ASP中时,IE发布按钮的标记而不是值属性是不兼容的.NET将使用onclick事件触发_doPostBack,所以我认为这不会是一个问题.

有什么理由我不应该用这个吗?如果没有,您将如何使用asp:Button或基于它的新服务器控件来支持它?如果可以避免的话,我宁愿不编写自己的服务器控件.


起初,<button runat="server">解决方案是有效的,但我立即遇到了一种情况,即它需要一个CommandName属性,而HtmlButton控件没有这个属性.看来我还是需要创建一个继承自Button的控件.

我需要做什么来覆盖render方法并使其呈现我想要的?


UPDATE

丹赫伯特的回答让我对再次找到解决方案感兴趣,所以我花了更多的时间来研究它.

首先,重载TagName有一种简单得多的方法:

public ModernButton() : base(HtmlTextWriterTag.Button)
{
}

Dan的解决方案的问题在于,标记的innerhtml被放入value属性中,这会导致回发时出现验证错误.一个相关的问题是,即使您正确呈现Value属性,IE的<button>标记的Braindead实现也会发布innerhtml,而不是value.因此,这一点的任何实现都需要重写AddAttributesToRender方法,以便正确呈现Value属性,并为IE提供某种解决方法,这样它就不会完全搞砸回发.

如果想利用数据绑定控件的CommandName/CommandArgument属性,IE问题可能无法解决.希望有人能提出解决办法.

我在渲染方面取得了进展:

ModernButton.cs

这将以正确的值呈现为一个正确的HTML<button>,但它不适用于ASP.Net回发系统.我已经写了一些我需要提供Command活动的东西,但它没有启动.

当用一个普通的asp:按钮并排判断这个按钮时,除了我需要的差异之外,它们看起来是一样的.所以我不确定ASP是如何实现的.Net正在连接本例中的Command事件.

另一个问题是,不会呈现嵌套的服务器控件(如ParseChildren(false)属性所示).在呈现期间将文本html文本注入控件非常容易,但是如何允许支持嵌套的服务器控件呢?

推荐答案

这是一个古老的问题,但对于我们这些不幸的人来说,仍然必须保持ASP.NET Web窗体应用程序,我自己也经历了这个过程,同时try 在内置按钮控件中包含 bootstrap 图示符.

根据Bootstrap文档,所需的标记如下:

<button class="btn btn-default">
    <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
    Search
</button>

我需要这个标记由服务器控件呈现,所以我开始寻找选项.

Button

这将是合乎逻辑的第一步,但是--正如这个问题所解释的--Button呈现的是<input>元素而不是<button>元素,因此不可能添加内部HTML.

LinkButton (credit to Tsvetomir Tsonev's answer)

Source个个

<asp:LinkButton runat="server" ID="uxSearch" CssClass="btn btn-default">
    <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
    Search
</asp:LinkButton>

Output个个

<a id="uxSearch" class="btn btn-default" href="javascript:__doPostBack(&#39;uxSearch&#39;,&#39;&#39;)">
    <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
    Search
</a>

Pros

  • 看起来不错
  • Command项;CommandNameCommandArgument物业

Cons

  • 渲染<a>而不是<button>
  • 呈现并依赖于引人注目的JavaScript

HtmlButton (credit to Philippe's answer)

Source个个

<button runat="server" id="uxSearch" class="btn btn-default">
    <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
    Search
</button>

Result

<button onclick="__doPostBack('uxSearch','')" id="uxSearch" class="btn btn-default">
    <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
    Search
</button>

Pros

  • 看起来不错
  • 渲染正确的<button>个元素

Cons

  • 没有Command项赛事;没有CommandNameCommandArgument处房产
  • 呈现并依赖于引人注目的JavaScript to handle its ServerClick event

现在很明显,没有一个内置控件看起来是合适的,所以下一个逻辑步骤是try 并修改它们以实现所需的功能.

Custom control (credit to Dan Herbert's answer)

NOTE: This is based on Dan's code, so all credit goes to him.

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属性(其值为Text).因为value<button>元素的有效属性,所以我决定为它包含一个属性.

Source个个

<%@ 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>

Output个个

<button type="submit" name="uxSearch" value="Foo" id="uxSearch" class="btn btn-default">
    <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
    Search
</button>

Pros

  • 看起来不错
  • 渲染一个适当的<button>元素
  • Command项;CommandNameCommandArgument物业
  • 不呈现或依赖突兀的JavaScript

Cons

  • 无(非内置控件除外)

Asp.net相关问答推荐

页面刷新后如何存储JS Select 数据

DataTables-如何修改来自JSON响应或其他DataTables参数的无结果(ZeroRecords)消息

Dotnet core 2.0 身份验证多模式身份 cookie 和 jwt

更改 GridView 中列的标题文本

是否可以使用 Membership API 更改用户名

无法让嵌套在 UpdatePanel 中的 WebControl 中的 ScriptManager.RegisterStartupScript 工作

返回 IHttpActionResult vs IEnumerable vs IQueryable

无法使用单例Microsoft.AspNetCore.Hosting.Internal.HostedServiceExecutor中的范围服务MyDbContext

无法确定条件表达式的类型,因为 'string' 和 'System.DBNull' 之间没有隐式转换

如何使用 asp.net 获取 html Select 的选定值

等价于 ASP.NET Core 中的 Html.RenderAction

不能在 DropDownList 中 Select 多个项目

ASP.NET Core 中的 NuGet 包位置在哪里?

ASP.net 中是否有 after Page_Load 事件

如何将参数传递给 ASP.NET MVC 2 中的自定义 ActionFilter?

VS 2010 中缺少 App_Code 文件夹

如何使用restsharp下载文件

使用 ASP.NET 进行重定向后获取

解析器错误:此处不允许使用_Default,因为它没有扩展类System.Web.UI.Page和 MasterType 声明

Windows 身份验证在本地 IIS 7.5 上不起作用.错误 401.1