如何将GridView中的行数作为参数传递给OnRowCommand调用

时间:2021-06-13 09:17:55

I am trying to make a button & checkbox display on a GridView dynamically only if there is more than 1 row in the GridView. (The view is results based on a search for users, so the number of rows is dynamic based on the search results)

我只是在GridView中有超过1行时,我试图在GridView上动态显示一个按钮和复选框。 (视图是基于搜索用户的结果,因此行数基于搜索结果是动态的)

The purpose of button and checkbox allow me to combine 2 or more user accounts. There is no point showing this button if there is only 1 row in the GridView (its confusing), so I set "Visible" parameter using a function. However, using GridViewID.Rows.Count in this function does not work. (What I figure it is actually the max number of rows displayed from when the call to function is taking place). ie: call from 2nd row of Gridview gives me Row.Count=2. So I am trying to pass a hidden control instead, but it is not working.

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

Here is my code:

这是我的代码:

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

The code behind function:

功能背后的代码:

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

I have created a Hidden field and tried to insert it into the GridView, but my code has a runtime error: (Note, I'm new to ASP :)

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

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

-- in function that populates GridView -- dt is the data source

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

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

The error I get is: System.Web.HttpException: DataBinding: 'MyASPPageName+dt' does not contain a property with the name 'NumberRowsGridView'.

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

So I'm basically doing this completely wrong.

所以我基本上这样做完全错了。

3 个解决方案

#1


This won't answer your question about how to do it in the markup, but when things get complicated like that, I like to go a simpler route. What you could do instead is hide/show the buttons once the entire GridView is bound.

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

Add the DataBound event to your GridView.

将DataBound事件添加到GridView。

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

Then in this event, all your rows will have been bound. So if you have more than one row, show the button. If not, hide the button. This should give you an idea.

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

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;
        }
    }
}

If you must do it in the markup, Enrique Zavaleta's answer should get you there.

如果你必须在标记中做到这一点,Enrique Zavaleta的答案应该会让你到那里。

#2


I'm not sure what you are trying to accomplish, but this should solve your problem:

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

Add a property like this in your code, the ViewState will keep your value through the life-cycle of the page.

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

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

now edit this part of your code like this

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

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

and the button markup like this

和这样的按钮标记

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

it should work properly

它应该正常工作

#3


Since OnRowCommand is an event you can get that information from your event handler. In your codebehind find the GridView1_RowCommand event handler and cast the object sender to GridView like this...

由于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!
}

As far as the other things you are wanting to do, you may want to create a new question that is more specific to those other tasks. But there is no need to pass the number of rows to the event handlers of a GridView because the sender object(the GridView that fired the event) will have all these properties. Hope this helps.

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

#1


This won't answer your question about how to do it in the markup, but when things get complicated like that, I like to go a simpler route. What you could do instead is hide/show the buttons once the entire GridView is bound.

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

Add the DataBound event to your GridView.

将DataBound事件添加到GridView。

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

Then in this event, all your rows will have been bound. So if you have more than one row, show the button. If not, hide the button. This should give you an idea.

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

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;
        }
    }
}

If you must do it in the markup, Enrique Zavaleta's answer should get you there.

如果你必须在标记中做到这一点,Enrique Zavaleta的答案应该会让你到那里。

#2


I'm not sure what you are trying to accomplish, but this should solve your problem:

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

Add a property like this in your code, the ViewState will keep your value through the life-cycle of the page.

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

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

now edit this part of your code like this

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

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

and the button markup like this

和这样的按钮标记

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

it should work properly

它应该正常工作

#3


Since OnRowCommand is an event you can get that information from your event handler. In your codebehind find the GridView1_RowCommand event handler and cast the object sender to GridView like this...

由于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!
}

As far as the other things you are wanting to do, you may want to create a new question that is more specific to those other tasks. But there is no need to pass the number of rows to the event handlers of a GridView because the sender object(the GridView that fired the event) will have all these properties. Hope this helps.

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