2

I would like to find a GridView Control within a separate class and I am having issues doing so. I even tried placing my code in the aspx.cs page to no avail. I keep getting Object reference not set to an instance of an object. I'm sure there is a simple step I'm missing, but in my research I cannot seem to find anything.

Aspx code

  <asp:GridView ID="GridView1" EnableViewState="true" 
    runat="server"  
    BackColor="White" BorderColor="#CC9966"
    BorderStyle="None" BorderWidth="1px" CellPadding="4" Width="933px" 
    onrowdatabound="GridView1_RowDataBound"  
    onrowdeleting="GridView1_RowDeleting" 
    onrowediting="GridView1_RowEditing"
    onrowupdating="GridView1_RowUpdating" 
    onsorting="GridView1_Sorting"
    AllowSorting="true"
    AutoGenerateColumns="False" 
    PersistedSelection="true" onrowcancelingedit="GridView1_RowCancelingEdit">
    <EditRowStyle Font-Size="Small" Width="100px" />
    <FooterStyle BackColor="#FFFFCC" ForeColor="#330099" />
    <Columns>
      <asp:TemplateField>
        <ItemTemplate>
          <asp:LinkButton runat="server" ID="EditLinkButton" CausesValidation="True"
                          Text="Edit" CommandName="Edit"/>
          <asp:LinkButton runat="server" ID="DeleteLinkButton" CausesValidation="False"
                          Text="Delete" CommandName="Delete"/>
        </ItemTemplate>
        <EditItemTemplate>
          <asp:LinkButton runat="server" ID="UpdateLinkButton" CausesValidation="True"
                          Text="Update" CommandName="Update"/>
          <asp:LinkButton runat="server" ID="CancelLinkButton" CausesValidation="False"
                          Text="Cancel" CommandName="Cancel"/>
        </EditItemTemplate>
      </asp:TemplateField>
    </Columns>
  </asp:GridView>

.cs code

protected void Page_Load(object sender, EventArgs e) {
  SetDirectory();

  System.Web.UI.Page page = (System.Web.UI.Page)System.Web.HttpContext.Current.Handler;
  GridView GridViewCopy = (GridView)page.FindControl("GridView1");

  Log.WriteLine("SortBindGrid: GridView Row Count: " + 
                GridViewCopy.Rows.Count, Log.DEBUG_LEVEL.TERSE);
  return;
}

I've tried a few variations of using MainContent_GridView for the find to get and Master.FindControl with all the same result.

Brian Mains
  • 50,520
  • 35
  • 148
  • 257
gcoleman0828
  • 1,541
  • 3
  • 30
  • 49

3 Answers3

5

In one of your comments you state that the GridView isn't on the Master Page, so is it safe to assume that it's on a page that uses a Master Page? And therefore it must be in a ContentPlaceholder control?

The key issue is that FindControl method only looks for direct children (emphasis added):

This method will find a control only if the control is directly contained by the specified container; that is, the method does not search throughout a hierarchy of controls within controls.

So you either need to:

  1. Search for the control within the correct ContentPlaceholder control, rather than from Page.
  2. Loop through each of the Controls in Page.Controls recursively until you find the control you're after.

An example of 2:

private Control FindControlRecursive(Control rootControl, string controlID)
{
    if (rootControl.ID == controlID) return rootControl;

    foreach (Control controlToSearch in rootControl.Controls)
    {
        Control controlToReturn = 
            FindControlRecursive(controlToSearch, controlID);
        if (controlToReturn != null) return controlToReturn;
    }
    return null;
}

Once you've got your control, you should cast it using as and then check for null just in case it's not quite what you were expecting:

var gridView = FindControlRecursively(Page, "GridView1") as GridView

if (null != gridView) {
  // Do Stuff
}
Zhaph - Ben Duguid
  • 26,785
  • 5
  • 80
  • 117
  • ok I will give all of this a whirl Ben. Thank you. The reason I mentioned MasterPage is because Ihave run into issues before where if there is a MasterPage involved (even if the control is not inside the site.master) there are changes in what you need to look for (ie. MainContent_controID) Thanks again I'll post how it goes – gcoleman0828 Jun 30 '11 at 00:07
  • Thank you everyone for your ideas and answers. code public static string GetControlName() { string controlName = ""; Control control = null; try { System.Web.UI.Page currentPage = (System.Web.UI.Page)System.Web.HttpContext.Current.Handler; control = currentPage.Master.FindControl("MainContent").FindControl("GridView1"); controlName = control.ClientID; } catch (Exception ex) { } return controlName; } – gcoleman0828 Jun 30 '11 at 02:11
0

Don't get the page from HttpContext if you are already within the page. Instead, is there a control you can use FindControl from? Instead of use page, use:

parentControl.FindControl("GridView1") as GridView;

Instead. There is an issue with finding the grid from the page level, and using a lower level control closer to the grid will have better success.

Brian Mains
  • 50,520
  • 35
  • 148
  • 257
  • @HTH I am guess you meant to Cast the right sidee to of type gris like this Grid GridView grid = (GridView)this.Master.FindControl("GridView1"); This did not work. are you sure you have to set an interface for it? seems kind of more than should be needed – gcoleman0828 Jun 29 '11 at 19:17
  • Also, not sure if I mentioned this, but the Grid is not part of the master page, but I know that theings have to be accessed differently when using a sitemaster – gcoleman0828 Jun 29 '11 at 19:20
  • Oh well then that changes everything. I thought it was in the master page. – Brian Mains Jun 29 '11 at 19:39
  • Brian- what would be the parentcontrol if the gridview is at the top? Do I have to put this in a panel for it to work? – gcoleman0828 Jun 29 '11 at 20:47
  • Sure, for testing purposes, try wrapping it with an and try using P1.FindControl("GridView1") and see if that works. – Brian Mains Jun 29 '11 at 23:25
  • Thank you everyone for your ideas and answers. `code public static string GetControlName() { string controlName = ""; Control control = null; try { System.Web.UI.Page currentPage = (System.Web.UI.Page)System.Web.HttpContext.Current.Handler; control = currentPage.Master.FindControl("MainContent").FindControl("GridView1"); controlName = control.ClientID; } catch (Exception ex) { } return controlName; }` – gcoleman0828 Jun 30 '11 at 00:49
0

Brian got it right but he forgot the essential part. You won't be able to do use his code unless you add this code on top of your HTML-Code of the file where you want to use it.(Page.aspx)

<%@ MasterType VirtualPath="~/Master/Site.master" %>

then you can use the code Brian suggested:

GridView grid = this.Master.FindControl("GridView1");

Edit: If you want to use the gridview from within another class in the same file i would use the following: Add this to the class created when you make the page

 public partial class YourPageName: System.Web.UI.Page
 {
    public static Gridview mygrid = this.GridviewnameOFYourASPX
    ...
 }

And to your custom class add this in your method

YourPageName.mygrid.(The changes you want to make);
Beejee
  • 1,836
  • 2
  • 17
  • 31
  • I must be missing something here. GridView grid = this.Master.FindControl("GridView1"); Yields the Error Error 2 Cannot implicitly convert type 'System.Web.UI.Control' to 'System.Web.UI.WebControls.GridView'. An explicit conversion exists I'm not sure how the above MasterType code will fix that? Also, I tried adding the MasterType in there and still does not work. I have a GridView Control that exists in Newpage.aspx, but have a Site.Master page. I want to access this GridView from within another generic class file that is in the same project. Can this be done? and if so how. – gcoleman0828 Jun 29 '11 at 19:33
  • FindControl returns a Control, which can't be assigned to a GridView variable. That is the error. However, if you aren't finding a control in the master page, you can't use the Master property. – Brian Mains Jun 29 '11 at 19:42
  • Is this what you wanted? Brian: You can do it normaly by doing ((GridView)this.Master.FindControl("GridView1")).Something(); – Beejee Jun 29 '11 at 20:17
  • The class I'm looking to access the control with a class that is in the same project but NOT the same file. It is a single .cs file, not aspx.cs. Will this still work bejee. Also the grid is Not in the site.master file. I was just mentioning that I have a master file... Do I still need to do a .master if it isn't in the master page? – gcoleman0828 Jun 29 '11 at 20:44
  • @Beejee, what I meant was, he said in a comment to my post, that the control isn't in the master page. – Brian Mains Jun 29 '11 at 23:27
  • Thank you everyone for your ideas and answers. End result proof of concept code : code public static string GetControlName() { string controlName = ""; Control control = null; try { System.Web.UI.Page currentPage = (System.Web.UI.Page)System.Web.HttpContext.Current.Handler; control = currentPage.Master.FindControl("MainContent").FindControl("GridView1"); controlName = control.ClientID; } catch (Exception ex) { } return controlName; } – gcoleman0828 Jun 30 '11 at 02:13