Dina
Dina

Reputation: 113

How do I pass the number of rows in GridView as an argument to OnRowCommand call

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)

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.

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

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

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

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

So I'm basically doing this completely wrong.

Upvotes: 1

Views: 825

Answers (3)

j.f.
j.f.

Reputation: 3949

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.

Add the DataBound event to your 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.

Upvotes: 2

Enrique Zavaleta
Enrique Zavaleta

Reputation: 2108

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.

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

Upvotes: 1

waltmagic
waltmagic

Reputation: 642

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

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.

Upvotes: 0

Related Questions