Reputation: 113
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
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
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
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