【问题标题】:Why adding/removing css classes like this won't work?为什么像这样添加/删除 css 类不起作用?
【发布时间】:2009-09-09 20:59:37
【问题描述】:

好的,我有一个像这样的 GridView

<asp:GridView ID="gv" runat="server" ... >
...
<HeaderStyle CssClass="header" />
<RowStyle CssClass="datarow" />
<AlternatingRowStyle CssClass="datarow alt" />
<Columns>
    <asp:TemplateField>
        <ItemTemplate>
            <asp:CheckBox runat="server" ID="gvchkDelete" />
        </ItemTemplate>
    </asp:TemplateField>
</Columns>
...
</asp:GridView>

注意自定义 RowStyleAlternatingRowStyle css 类。 我想要的是在选中 gvchkDelete CheckBox 时更改行的样式,并在未选中时将其删除。所以我想出了这样的东西:

protected void gv_PreRender(object sender, EventArgs e)
{
    DUtil.GridViewRowHighlight(gv, "gvchkDelete");
}

//External Class
public class DUtil
{
public static void GridViewRowHighlight(GridView gv, string CheckBoxControlID)
{
    foreach (GridViewRow gvr in gv.Rows) {
        GridViewRowHighlight(gvr, CheckBoxControlID);
    }
}

public static void GridViewRowHighlight(GridViewRow gvr, string CheckBoxControlID)
{
    string scriptFormat = "if(this.checked){{document.getElementById('{0}').className+=' {1}';}}else{{document.getElementById('{0}').className=document.getElementById('{0}').className.replace('{1}','');}};";
    string script = String.Format(scriptFormat, gvr.ClientID, DEstilos.HighlightStyle);
    CheckBox chk = (CheckBox)gvr.FindControl(CheckBoxControlID);
    if (chk.Checked) AddCssClass(gvr, DEstilos.HighlightStyle);
    else RemoveCssClass(gvr, DEstilos.HighlightStyle);
    chk.Attributes.Add("onclick", script);
}

public static void AddCssClass(WebControl control, string cssClass)
{
    List<string> classes = new List<string>(control.CssClass.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
    classes.Add(cssClass);
    control.CssClass = ToDelimitedString(classes, " ");
}

public static void RemoveCssClass(WebControl control, string cssClass)
{
    List<string> classes = new List<string>(control.CssClass.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
    classes.Remove(cssClass);
    control.CssClass = ToDelimitedString(classes, " ");
}

public static string ToDelimitedString(IEnumerable<string> list, string delimiter)
{
    StringBuilder sb = new StringBuilder();
    foreach (string item in list) {
        if (sb.Length > 0)
            sb.Append(delimiter);

        sb.Append(item);
    }
    return sb.ToString();
}
//End class
}

//External Class
public class DEstilos
{
public const string HighlightStyle = "highlight";
//End Class
}

所有这些都是:为 gridview.Rows 集合中的每个复选框添加一个 JavaScript 函数到复选框的 onclick 属性,以便在单击复选框的父行时添加/删除突出显示样式。此外,如果复选框默认选中/取消选中,则添加/删除突出显示样式。

所有这一切只是为了确保无论何时进行回发,带有选中复选框的行都会保留突出显示样式(当然,仅通过启用视图状态不会发生巫术)。问题是在 gridview 的标记中定义的 RowStyleAlternatingRowStyle css 类似乎正在“ignored”或“removed”,为什么?

更新:不使用 jQuery 或 Prototype 的解决方案会更好,除非这是这样做的唯一方法。

更新 2、3:如果您删除这些行:

if (chk.Checked) AddCssClass(gvr, DEstilos.HighlightStyle);
else RemoveCssClass(gvr, DEstilos.HighlightStyle);

从 GridViewRowHighlight 方法,然后将 RowStyle 和 AlternatingRowStyle css 类 DO 添加到 HTML 标记中,我得到了想要的效果,但是在每次回发时,突出显示效果被删除,而复选框保持这是以前的状态。

感谢您的帮助!

【问题讨论】:

  • “类”属性是否在运行时呈现在输出 HTML 中?
  • 只有当我不弄乱 WebControls 的 CssClass 属性时,才会添加在 Row 和 alteringRow 样式中定义的 css 类。

标签: c# asp.net css


【解决方案1】:

听起来你有两个问题:

  1. 在呈现页面时,您设置的 CSS 类未得到遵守。
  2. 您希望网格每一行的复选框行为来切换其父网格行的样式。

试试这个解决问题 #2:

&lt;asp:CheckBox runat="server" ID="gvchkDelete" /&gt; 更改为&lt;asp:CheckBox runat="server" ID="gvchkDelete" OnClientClick="javascript:ToggleHighlight(this);" /&gt;

添加这个 javascript 函数并确保它可以被您加载的页面访问:

function ToggleHighlight(elem)
{  
  if(!elem)
  {
    return;
  }

  var gridRow = elem;

  while(gridRow.tagName != "TR" && gridRow.parentNode)
  {
    gridRow = gridRow.parentNode;
  }

  gridRow.className = elem.checked ? 
                      (gridRow.className + " highlight") :
                      gridRow.className.replace("highlight", "");
}

至于问题 #1,请确认您的 CSS 样式确实进入了渲染页面。

对于绕过服务器端代码的替代方法,您可以在页面加载时执行以下操作(这使用 jQuery 库):

$(document).ready
(
  function()
  {
    $("input[id$=gvchkDelete]")
      .each
      (
        function()
        {
          ToggleHighlight(elem);
        }
      );
  }
);

【讨论】:

  • 当我删除更新 2,3 上的行时。 css 被正确地重新渲染。
  • @Unlimited071:该代码必须存在。如果我弄错了,请纠正我,但第一页加载没有选择任何内容。您的点击处理程序工作正常,因此行将正确突出显示。但是,当您回帖时,所有颜色都会丢失。这就是您需要删除的代码的原因。
  • @David:是的,没错。这就是我把它放在首位的原因,但是如果我保持这些行不变,那么在 rowstyle 和alternatingrowstyle 标签中定义的类就不会进入 HTML
  • @Unlimited071:GridView 控件具有 SelectedRowStyle 属性。你可以用这个代替吗?有关详细信息,请参阅msdn.microsoft.com/en-us/library/…
  • @Unlimited071:我添加了一种面向 JavaScript/jQuery 的方法,该方法将在客户端页面加载后突出显示行。这种方法将允许您删除服务器端的类分配。
【解决方案2】:

我相信这是 jQuery 的主要候选者。使用 jQuery 调整 HTML 控件的 CSS 类很容易。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 2012-03-20
    • 2022-12-26
    • 2021-09-30
    相关资源
    最近更新 更多