【问题标题】:Clickable Webcontrol, ASP.NET可点击的 Web 控件,ASP.NET
【发布时间】:2012-05-08 13:54:02
【问题描述】:

这是与my last question 相关的问题,以防您需要更多背景信息。

我的问题是:是否可以让 asp.net 表格中的单元格可点击?

或者是否至少可以在 ASP.NET 中制作一个可点击的 WebControl(应该可以放置在 ControlCollection 中),而不是 Button 或 LinkBut​​ton? 如果没有,是否可以将多行信息放入按钮文本中?

我尝试将其他组件添加到按钮的 ControlCollection(我已经看到在 Button 的 Windows 窗体版本中工作),以查看是否可以将子组件呈现到按钮,但没有成功:

private void ModifyTableCell(TableCell cell)
{
    //Create new button
    Button btnCell = new Button();
    btnCell.Click += (sender, args) =>
    {
        //Event for the button
    };

    //Create new Label
    Label lblCell = new Label();
    lblCell.Font.Bold = true;
    lblCell.Text = "This text won't appear";

    btnCell.Controls.Add(lblCell); //Attempt to add label to Button
    cell.Controls.Add(btnCell);
}

编辑:我最终只是为整个单元格创建了一个多行链接按钮。

【问题讨论】:

    标签: c# asp.net button web-controls


    【解决方案1】:

    通过分配onclick 属性并利用__doPostBack 函数,您应该能够使几乎所有控件都可点击。

    ctrl.Attributes["onclick"] = string.Format("__doPostBack('{0}', '{1}');", ctrl.ClientID, "SomeArgument");
    

    您也可以使用GetPostBackEventReference 方法。这个选项实际上更安全,因为它会注册它不存在的__doPostBack 函数:

    ctrl.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(ctrl, string.Empty);
    

    然后,在代码隐藏中,您可以简单地覆盖 RaisePostBackEvent 方法:

    protected override void RaisePostBackEvent(IPostBackEventHandler source, string eventArgument)
    {
        base.RaisePostBackEvent(source, eventArgument);
    
        if (eventArgument == "SomeArgument") //using the argument
        {
            //do whatever
        }
    }
    

    【讨论】:

    • +1。 Page.ClientScript.GetPostBackEventReference 方法也是 __doPostBack 的替代方法。见stackoverflow.com/questions/8771097/…
    • 由于在 RaisePostBackEvent 方法的 if-check 中我不能有一个指向动态创建控件的变量,除非我必须先将它们添加到列表中,否则我可以我真的不知道这会如何工作。澄清一下:这实际上是添加一个 onclick 属性,假装它是在 aspx 文件中创建的,然后被转换,然后当调用 RaisePostBackEvent 时,它被调用。还是我理解错了?
    • 为什么不能只使用参数来满足您的条件?请参阅我的更新答案。
    • 是的,我可以,我没想到。但是我对这个解决方案的本质是正确的吗?我想了解发生了什么。
    • 这个解决方案基本上劫持了所有其他能够回发的控件所使用的 JavaScript 函数。
    【解决方案2】:

    您可以使用字符串生成器向 asp.net 按钮添加多行,例如:

    System.Text.StringBuilder buttonText = new System.Text.StringBuilder();
    buttonText.AppendLine("first line");
    buttonText.AppendLine("second line");
    btnMultiline.Text = buttonText.ToString;
    

    【讨论】:

      【解决方案3】:

      我不确定您如何想象这样一个复合控件会被呈现。请记住,每个 ASP.NET 控件最终都会输出 HTML。 You Button 本质上是输出一个

      <input type="button">The button text</input>
      

      如果您想在&lt;input&gt; 标记内放置任何其他内容,则它必须与 HTML 兼容。我不确定输入标签是否允许其他 HTML。

      另一方面,如果它是 LinkBut​​ton,则生成的 HTML 标记是 &lt;a href=""&gt; 标记。你可以放任何东西,如果你愿意的话,甚至是一张图片,它会变成可点击的。

      我不确定您的完整方案是什么,但是您尝试做的事情闻起来很糟糕。我建议你要么使用 LinkBut​​ton,要么重新考虑你的方法,只要记住 HTML 的最终输出是什么。

      【讨论】:

      • 您可以看到我在问题第一行中发布的链接中描述的完整场景。是的,html 渲染也是我的一个担心。但如果我能找到一个更简单灵活的解决方案,我会很乐意这样做。
      【解决方案4】:

      在阅读您的两个帖子时,您似乎希望能够单击单元格中的任何内容并将其回发,就好像整个单元格是一个按钮一样?

      如果是这样,其中一种相当简单的方法是构建您的单元格内容,就像您不尝试回发时一样。然后添加一个样式为display:none; 的按钮。然后,您可以使用客户端脚本来捕获单元格的单击事件,并引发按钮的单击事件以导致回发。

      这允许您以任何您喜欢的方式创建单元格内容,并且会自动为您生成回发代码和处理程序。

      使用 JQuery 你会得到类似这样的结果:

      <head runat="server">
          <style>
              input.ClickableCellButton
              {
                  display: none;
              }
          </style>
      </head>
      <body>
          <form id="form1" runat="server">
          <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js" type="text/javascript"></script>
          <script type="text/javascript">
              $(document).ready(function () {
                  $("td.ClickableCell").click(function (event) { $(event.target).children("input.ClickableCellButton").click() });
              });
          </script>
          <div>
              <table>
                  <tbody>
                      <tr>
                          <td class="ClickableCell">
                              Cell Contents<br />
                              on multiple lines
                              <asp:Button ID="Button1" runat="server" Text="Button" CssClass="ClickableCellButton"
                                  OnClick="Button1_Click" />
                          </td>
                      </tr>
                  </tbody>
              </table>
          </div>
          </form>
      </body>
      

      【讨论】:

      • 这正是我想要实现的。但是你写的行(“Cell Contents
        on multiple lines”)不会在按钮旁边创建吗?
      • 因为按钮的样式是display:none,所以它在浏览器中是不可见的。这意味着从用户的角度来看它不存在,但我们的 javascript 仍然可以看到它并引发与之关联的事件。所以本质上这会将整个单元格变成一个按钮。
      • 我误解了您的解决方案。我认为单元格内的按钮是引发点击事件的按钮。但是既然这是一个动态创建的asp:Table,那么如何使用添加JQuery来实现呢?我找到了样式的 control.Style.Add() 方法。
      • JQuery snip 解析为英文:当文档完成加载后,扫描它以查找所有具有 ClickableCell 类的 td 元素。对于找到的每个元素,注册一个单击事件处理程序以执行此匿名函数。处理函数说:获取事件的目标(被点击的 td),在目标内部查找具有 ClickableCellButton 类的输入(单元格中的按钮控件),引发位于的输入的点击事件(调用按钮预建的回发代码)。
      • 通过在页面上包含 JQuery snip,并在创建适当的控件时为其分配正确的类名,这样客户端代码就可以找到带有内容/按钮的单元格和处理将点击事件从 td 元素中继到不可见按钮。这为您提供了按钮的所有回发功能(命令参数等)以及表格单元格的所有格式化功能(多行、自动宽度等),而无需尝试编写自己的回发代码。
      【解决方案5】:

      如果没有,是否可以将多行信息放入 按钮文字?

      对于这种特殊情况,您只能通过 CSS 来完成;无需扩展 Button:

      <asp:button id="myMultilineButton" runat="server" style="width:60px; white-space: normal;" Text="Several lines of text" />
      

      它将呈现为:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-13
        • 1970-01-01
        • 2016-09-13
        • 1970-01-01
        相关资源
        最近更新 更多