【问题标题】:How do I pass the number of rows in GridView as an argument to OnRowCommand call如何将 GridView 中的行数作为参数传递给 OnRowCommand 调用
【发布时间】:2015-05-13 20:20:51
【问题描述】:

我试图在 GridView 上动态显示按钮和复选框,仅当 GridView 中有超过 1 行时。 (视图是基于用户搜索的结果,所以行数是根据搜索结果动态变化的)

按钮和复选框的用途是让我可以组合 2 个或更多用户帐户。如果 GridView 中只有 1 行(令人困惑),则显示此按钮毫无意义,因此我使用函数设置了“可见”参数。但是,在此函数中使用 GridViewID.Rows.Count 不起作用。 (我认为它实际上是调用函数时显示的最大行数)。即:从 Gridview 的第二行调用给我 Row.Count=2。所以我试图通过一个隐藏的控件来代替,但它不起作用。

这是我的代码:

<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand">
<Columns>
        <asp:TemplateField ShowHeader="false">
            <ItemTemplate>
                <asp:HiddenField ID="HiddenUserID" runat="server" Visible="false" Value= '<%#Eval("UserID") %>' ></asp:HiddenField> 
                    <asp:HiddenField ID="NumberRowsGridView" runat="server" Visible="false" Value='<%#Bind("NumberRowsGridView") %>'></asp:HiddenField>
            </ItemTemplate>
            </asp:TemplateField>
            <asp:BoundField DataField="UserName" HeaderText="User Name"/>
            <asp:BoundField DataField="Email" HeaderText="Email Address"/>
 <asp:TemplateField ShowHeader="false">
        <ItemTemplate>
                <asp:CheckBox ID="CheckBox1" runat="server" Visible='<%# ShowMergeUserButton((String)Eval("UserName"),(String)Eval("Email"),(String)Eval("NumberRowsGridView")) %>' />
            </ItemTemplate>
     </asp:TemplateField>

     <asp:TemplateField ShowHeader="True" HeaderText="Merging Actions">
        <ItemTemplate>
                <asp:Button ID="Button3" runat="server" CausesValidation="false" CommandName="MergeIntoUser"
                    Text="Merge Into This Account" CommandArgument='<%# Container.DataItemIndex + "," + Eval("UserID")%>' Visible='<%# ShowMergeUserButton((String)Eval("UserName"),(String)Eval("Email"),(String)Eval("NumberRowsGridView")) %>'/>
            </ItemTemplate>
 </asp:TemplateField>
     </Columns>

函数背后的代码:

protected Boolean ShowMergeUserButton(String Username, String Email, String NumRows)
{
return (Username == Email && Convert.ToInt32(NumRows) > 1);
}

我创建了一个隐藏字段并尝试将其插入到 GridView 中,但我的代码出现运行时错误:(注意,我是 ASP 新手 :)

protected System.Web.UI.WebControls.HiddenField NumberRowsGridView;

-- 在填充 GridView 的函数中 -- dt 是数据源

GridView1.DataSource = dt; 
GridView1.DataBind();
NumberRowsGridView.Value = dt.Count<items>().ToString();

我得到的错误是: System.Web.HttpException:DataBinding:“MyASPPageName+dt”不包含名为“NumberRowsGridView”的属性。

所以我基本上做错了。

【问题讨论】:

    标签: c# asp.net gridview


    【解决方案1】:

    这不会回答您关于如何在标记中执行此操作的问题,但是当事情变得如此复杂时,我喜欢走一条更简单的路线。您可以做的是在绑定整个 GridView 后隐藏/显示按钮。

    DataBound 事件添加到您的 GridView。

    <asp:GridView ID="GridView1" runat="server"
        OnRowCommand="GridView1_RowCommand"
        OnDataBound="GridView1_DataBound">
    

    那么在这种情况下,您的所有行都将被绑定。因此,如果您有多于一排,请显示该按钮。如果没有,请隐藏按钮。这应该会给你一个想法。

    protected void GridView1_DataBound(object sender, EventArgs e)
    {
        if (GridView1.Rows.Count > 1)
        {
            foreach (GridViewRow row in GridView1.Rows)
            {
                Button Button3 = (Button)row.FindControl("Button3");
                Button3.Visible = true;
            }
        }
    }
    

    如果您必须在标记中执行此操作,Enrique Zavaleta 的回答应该可以帮助您。

    【讨论】:

    • 好了! @Dina 的好答案...击败我 j.f ;)
    • 这确实简化了代码并将所有内容放在一个位置。完成!
    【解决方案2】:

    我不确定您要完成什么,但这应该可以解决您的问题:

    在您的代码中添加这样的属性,ViewState 将在页面的整个生命周期中保持您的价值。

    public string NumberRowsGridView
    {
        get { return ViewState["NumberRowsGridView"] == null ? null : ViewState["NumberRowsGridView"].ToString(); }
        set { ViewState["NumberRowsGridView"] = value; }
    }
    

    现在像这样编辑这部分代码

    NumberRowsGridView = dt.Count<items>().ToString();
    GridView1.DataSource = dt; 
    GridView1.DataBind();
    

    还有这样的按钮标记

    <asp:Button ID="Button3" runat="server" ... Visible='<%# ShowMergeUserButton((String)Eval("UserName"),(String)Eval("Email"), NumberRowsGridView) %>'/>
    

    它应该可以正常工作

    【讨论】:

    • 谢谢!只是好奇它需要是一个视图状态吗?请注意,我要做的是仅在满足某些条件时才显示按钮。
    • 我不确定你的目标是什么,但如果 NumberRowsGridView = dt.Count().ToString();行在与 ShowMergeUserButton 相同的回发中被调用,一个简单的公共变量应该可以工作
    【解决方案3】:

    由于 OnRowCommand 是一个事件,您可以从事件处理程序中获取该信息。在您的代码隐藏中找到 GridView1_RowCommand 事件处理程序并将对象发送者转换为 GridView 像这样...

    void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
    {
        GridView gridView = (GridView)sender;
        int numOfRows = gridView.Rows.Count;
        // Now you can  do something with numOfRows!
    }
    

    就您想做的其他事情而言,您可能想要创建一个更具体针对其他任务的新问题。但是没有必要将行数传递给 GridView 的事件处理程序,因为发送者对象(触发事件的 GridView)将具有所有这些属性。希望这会有所帮助。

    【讨论】:

    • tx @waltmagic,但这是对不同于 GridView1_RowCommand 的函数的调用。我说的是这部分 Visible='
    • @Dina,我不会那样做,这不是他们所说的好习惯。也许您应该编辑您的问题并删除除 html/asp 之外的所有代码,然后描述您要执行的操作。这样你会得到更好的答案。
    • @Dina 如果 GridView 有不止一行,您希望可见 = true,对吗?所以也许用 GridView1_DataBound 事件处理程序处理 DataBound 事件。如果相关控件上的 numOfRows > 1 visible = true
    • 是的!我根本不明白 DataBound 是什么意思,所以这是一个很好的学习示例。
    • 这就是我喜欢 StackOverflow 的原因......我也一直在这里学习 :D 很高兴我们能帮助你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    相关资源
    最近更新 更多