PageHelper.RecursiveFindControl

For general questions and discussions specific to the AbleCommerce 7.0 Asp.Net product.
Post Reply
User avatar
jmestep
AbleCommerce Angel
Posts: 8164
Joined: Sun Feb 29, 2004 8:04 pm
Location: Dayton, OH
Contact:

PageHelper.RecursiveFindControl

Post by jmestep » Mon Dec 22, 2008 6:48 pm

I'm trying to access an image field in a row of a gridview and feed it an image URL and can't do that so I have taken the image tag and put it in a page with nothing else on it. How would I find the image now? Here is the page code.
<body>
<form id="form1" runat="server">
<div>
<asp:Image ID="Image1" runat="server" />
</div>
</form>
</body>
Thanks
Judy Estep
Web Developer
jestep@web2market.com
http://www.web2market.com
708-653-3100 x209
New search report plugin for business intelligence:
http://www.web2market.com/Search-Report ... -P154.aspx

User avatar
mazhar
Master Yoda
Master Yoda
Posts: 5084
Joined: Wed Jul 09, 2008 8:21 am
Contact:

Re: PageHelper.RecursiveFindControl

Post by mazhar » Tue Dec 23, 2008 2:16 am

If this the only control on the page then you cab access it directly through its ID means using Image1

User avatar
jmestep
AbleCommerce Angel
Posts: 8164
Joined: Sun Feb 29, 2004 8:04 pm
Location: Dayton, OH
Contact:

Re: PageHelper.RecursiveFindControl

Post by jmestep » Tue Dec 23, 2008 7:34 am

I was searching the forum and found out that I had posted a similar question back in November! If I use the RecursiveFindControl in this example, what do I put for the first argument?
public static Control RecursiveFindControl(Control parent, string controlId)
Judy Estep
Web Developer
jestep@web2market.com
http://www.web2market.com
708-653-3100 x209
New search report plugin for business intelligence:
http://www.web2market.com/Search-Report ... -P154.aspx

User avatar
sohaib
Developer
Developer
Posts: 1079
Joined: Fri Jan 23, 2004 1:38 am

Re: PageHelper.RecursiveFindControl

Post by sohaib » Tue Dec 23, 2008 7:44 am

Hello Judy,

...edited....
I re-read your post and realized you are trying to use with GridView control ... Please see my next post.

User avatar
AbleMods
Master Yoda
Master Yoda
Posts: 5170
Joined: Wed Sep 26, 2007 5:47 am
Location: Fort Myers, Florida USA

Re: PageHelper.RecursiveFindControl

Post by AbleMods » Tue Dec 23, 2008 7:45 am

Judy, you can access objects within a gridview control by direct-casting to them in the gridview control methods.

For instance, look at ~/Admin/Orders/Default.aspx.cs. Able uses a Gridview control called "OrderGrid" in the HTML-side and interacts with it in the code-behind.

In the code-behind, they have a function

Code: Select all

protected void OrderGrid_RowCommand(object sender, GridViewCommandEventArgs e)
This method fires whenever a Gridview command button is pressed in the grid. The current row of the button that was pressed is passed as a parameter. Since the current row is passed, you can direct-cast that row or its contents into a new variable that represents the control you want. If you direct-cast it into a Row object, then you can do a findcontrol within that row object to locate the control (by Id like "Image1") you want to manipulate.

The key is remembering that everything in .Net is a "container". Normally you search a "page container" for a control like a textbox or image. But when a gridview is involved, you have remember the container hiearchy has changed and is now "Page->GridView->GridRow".

The gridview control lets you hook into all sorts of functions. So you can do your stuff when the gridview loads a row, displays a row, refreshes a row, when a command button is pressed etc.

Now, to extend it further for a sec. Let's say you have a gridview on the ac_Products table. But you want the product Thumbnail image to be in the gridview instead of the actual thumbnail image URL. That becomes very easy - on the HTML side just make one of the columns:

Code: Select all

<ASP:Image runat="server" Imageurl="<% EVAL("ImageUrl") %>"></Image>
So you don't even have to call any functions or anything. You just tell the gridview to "substitute" the ac_products.ImageUrl value into the parameter for the Image control. Normally you do this in a gridview template field so it's easier to control layout.

~/Admin/Orders/Default.aspx and .aspx.cs has some great examples of working with gridview controls, methods, template fields and even calculated fields.

If you want to use RecursiveFindControl(), you have to pass it the container object. In your case, it would be the page. But given the example you provided, you shouldn't have to do it. In your example code, you would just reference it as Image1.ImageUrl = "~/Mypic.jpg" or Image1.Width=200 etc.
Joe Payne
AbleCommerce Custom Programming and Modules http://www.AbleMods.com/
AbleCommerce Hosting http://www.AbleModsHosting.com/
Precise Fishing and Hunting Time Tables http://www.Solunar.com

User avatar
sohaib
Developer
Developer
Posts: 1079
Joined: Fri Jan 23, 2004 1:38 am

Re: PageHelper.RecursiveFindControl

Post by sohaib » Tue Dec 23, 2008 7:59 am

The PageHelper.RecursiveFindControl method tries to find a sub-control with given id inside a given parent-control. You may need this in situations where you can have more than one control of the same name in your page. This can happen for example in a GridView control. At the design time you only specify the template of an item but when the page actually gets built at run-time there are hundreds of items against that template. If you want to refer to one of them you can not use its ID specified in the template. Say you have 4 fields to display in a grid view an one filed as a check-box to indicated whether the particular item has been selected or not. If you want to provide the user with an option to select a few items and delete them then, once the user clicks delete button after selecting a few items you need to figure out in the code which items were selected. One way to do this could be something like this

Code: Select all

        List<int> selectedIds = new List<int>();
        foreach (GridViewRow row in MyGrid.Rows)
        {
            CheckBox selected = (CheckBox)PageHelper.RecursiveFindControl(row, "SelectedChkBox");
            if ((selected != null) && selected.Checked)
            {
                selectedId.Add((int)MyGrid.DataKeys[row.DataItemIndex].Values[0]);
            }
        }
Note that the parent for 'SelectedChkBox' passed to RecursiveFindControl is the 'GridViewRow' control that is immediate parent of it. There will be only one 'SelectedChkBox' item per row but there will be many 'SelectedChkBox' items in the whole grid.

User avatar
jmestep
AbleCommerce Angel
Posts: 8164
Joined: Sun Feb 29, 2004 8:04 pm
Location: Dayton, OH
Contact:

Re: PageHelper.RecursiveFindControl

Post by jmestep » Tue Dec 23, 2008 9:42 am

I've been looking at that code in the Admin/Orders/Default.aspx and can't see why I'm not able to it in my code. Here is the section for the gridview display:

Code: Select all

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
         <ContentTemplate>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
            AllowPaging="True" PageSize="50" 
            OnPageIndexChanging="GridView1_PageIndexChanging" CellPadding="5">
            <PagerSettings Position="TopAndBottom" />
        <Columns>
        <asp:TemplateField HeaderText = "Image">
        <ItemTemplate>
            <asp:Image ID="Image1" width="50px" runat="server"/>
       </ItemTemplate>
        </asp:TemplateField>
         <asp:TemplateField HeaderText = "File URL">
         <ItemTemplate>         
         <asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl='<%#string.Format("~/Assets/OrderUploads/"+ Eval("Name")) %>'
               Text='<%#Eval("Name") %>' ></asp:HyperLink>
        </ItemTemplate>
        </asp:TemplateField>
        </Columns>
            <AlternatingRowStyle BackColor="White" />
        </asp:GridView>             
        </ContentTemplate>
        </asp:UpdatePanel>
I've even tried taking the gridview out of the update panel, but that didn't help.
Here is the section of code where I'm trying to push the image to the gridview- right now, I've got a static image to eliminate any errors with conditional code. If I had code the "~/images/up.gif" in <asp:image tag, it shows up so I know the path is valid.

Code: Select all

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {   
       foreach(GridViewRow row in GridView1.Rows)
        //if (e.Row.RowType == DataControlRowType.DataRow) // make sure this is not a header or footer row
        {
            Image img = (Image)PageHelper.RecursiveFindControl(row, "Image1");
     
                img.ImageUrl = "~/images/up.gif";    // set image url to something else
        }
       
    } 
Thanks
Judy Estep
Web Developer
jestep@web2market.com
http://www.web2market.com
708-653-3100 x209
New search report plugin for business intelligence:
http://www.web2market.com/Search-Report ... -P154.aspx

User avatar
sohaib
Developer
Developer
Posts: 1079
Joined: Fri Jan 23, 2004 1:38 am

Re: PageHelper.RecursiveFindControl

Post by sohaib » Tue Dec 23, 2008 9:59 am

You are invoking this on 'RowDataBound' event... there is no need for looping through each row of the grid ... you already get a reference of the row in this event
This should work I suppose...

Code: Select all

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{     
    if (e.Row.RowType == DataControlRowType.DataRow) // make sure this is not a header or footer row
    {
        Image img = (Image)PageHelper.RecursiveFindControl(e.Row, "Image1");
        img.ImageUrl = "~/images/up.gif";    // set image url to something else
    }
} 
Make sure that you actually have 'GridView1_RowDataBound' method assigned for OnRowDataBound event in your grid view definition.

User avatar
jmestep
AbleCommerce Angel
Posts: 8164
Joined: Sun Feb 29, 2004 8:04 pm
Location: Dayton, OH
Contact:

Re: PageHelper.RecursiveFindControl

Post by jmestep » Tue Dec 23, 2008 10:04 am

Duh, this was the missing link:
Make sure that you actually have 'GridView1_RowDataBound' method assigned for OnRowDataBound event in your grid view definition.
I had it in the code behind but not on the gridview on the page.

Now I think I can sleep at night!

Thanks to all of you.
Judy Estep
Web Developer
jestep@web2market.com
http://www.web2market.com
708-653-3100 x209
New search report plugin for business intelligence:
http://www.web2market.com/Search-Report ... -P154.aspx

User avatar
AbleMods
Master Yoda
Master Yoda
Posts: 5170
Joined: Wed Sep 26, 2007 5:47 am
Location: Fort Myers, Florida USA

Re: PageHelper.RecursiveFindControl

Post by AbleMods » Tue Dec 23, 2008 10:08 am

Visual Studio doesn't help the matter - it auto-hooks the events in a regular .ASPX page but it doesn't necessarily auto-hook them in a code-behind file. I had to get myself into the habit of always using the VS drop downs to select the object and then select the event - that way the hook is always established.

Oh if I could share the hours I've spent debugging why an event refuses to fire only to realize I never hooked it the control :)
Joe Payne
AbleCommerce Custom Programming and Modules http://www.AbleMods.com/
AbleCommerce Hosting http://www.AbleModsHosting.com/
Precise Fishing and Hunting Time Tables http://www.Solunar.com

Post Reply