0

I have a FormView and I need to access some Divs and other controls that are inside it. My apsx code looks similar to this:

 <asp:FormView ID="Edit_FV" runat="server" DataKeyNames="IDproceso" DefaultMode="Edit" DataSourceID="SqlDS_Procesos">
            <EditItemTemplate>
                <div id="second_info" runat="server">
                    <div id="second_info_left" runat="server">
                        <div id="alcance" class="report_field" runat="server">
                            <p class="container-title">
                                Alcance:</p>
                            <asp:TextBox ID="TextBox14" runat="server" TextMode="multiline" Width="400px" Height="120px" Text='<%# Bind("alcance") %>' />
                        </div> 
                    </div>
                    <div id="second_info_right" runat="server">
                    <div class="valores-container" id="tipo_ahorro" runat="server">
                        <asp:CheckBox ID="ahorro_state" runat="server" Checked='<%# Bind("tipo_ahorro") %>'  />
                    </div>
                </div>
            </EditItemTemplate>
        </asp:FormView>

Now, say I want to access the CheckBox with id = ahorro_state, I tried with Edit_FV.FindControl("ahorro_state") and got a Null reference. I also tried with Edit_FV.FindControl("MainContent_Edit_FV_ahorro_state") because this is how the ID actually gets named in the final HTML document, but I got a Null reference too. The same happened when I tried accessing any of the divs (with IDs second_info,tipo_ahorro, etc..). I feel I'm doing a dumb mistake but I looked around a bit and haven't found and answer.

Any ideas how to solve this?

EDIT: Added Code where I'm calling FindControl.

I tried both calling DataBind() from the Page_Load():

protected void Page_Load(object sender, EventArgs e)
        {

            DataBind();
            if (Edit_FV.CurrentMode == FormViewMode.Edit)
            {
                Control c = Edit_FV.FindControl("ahorro_state");//c is null here.
            }
        }

And also tried setting the OnDataBound attribute of Edit_FV: OnDataBound="onBound"

   protected void onBound(object sender, EventArgs e)
            {
                if (Edit_FV.CurrentMode == FormViewMode.Edit)
                {
                    ControlCollection a = Edit_FV.Controls;
                    Control c = Edit_FV.FindControl("ahorro_state");//c is null here
                }

            }
leonsas
  • 4,718
  • 6
  • 43
  • 70

2 Answers2

1

Although the default mode is set "Edit", the form view won't switch to that mode until the control is DataBound. Try calling DataBind() first, then use FindControl using the ID of your element (not the ClientID, as you tried in your second example).

See FormView.FindControl(): object reference error for examples of where to put your FindControl logic.

EDIT:

There is also the possibility that your data source is not returning any data. This will result in the EditItemTemplate being empty which might explain your null reference errors. Try checking for a Edit_FV.DataItemCount > 0 before switching into Edit mode.

Community
  • 1
  • 1
Derek Hunziker
  • 12,996
  • 4
  • 57
  • 105
1

I have had similar problems with 'FindControl'. I found a piece of code that has helped me
a) Find controls recursively, and
b) the debug statement has been very help to see why I am not finding the control in question.
To help me find the controls I have to give them ID values when I am looking for them if they don't have one by default:

    public static class General_ControlExtensions
{
    //From: http://www.devtoolshed.com/content/find-control-templatefield-programmatically
    /// <summary>
    /// recursively finds a child control of the specified parent.
    /// USAGE: 
    /// Control controlToFind = DetailsView1.fn_ReturnControl_givenControlID("txtName");
    /// </summary>
    /// <param name="rootControl"></param>
    /// <param name="ID"></param>
    /// <returns></returns>
    public static Control fn_ReturnControl_givenControlID(this Control rootControl, string ID)
    {
        if (rootControl.ID == ID)
        {
            return rootControl;
        }
        foreach (Control control in rootControl.Controls)
        {

            Debug.WriteLine("FindByID - child.id: " + control.ID);
            Control foundControl = fn_ReturnControl_givenControlID(control, ID);
            if (foundControl != null)
            {
                return foundControl;
            }
        }
        return null;
    }

Here is an example of its usage:

using System.Diagnostics;   // for debug 

TextBox txt_LastName = (TextBox)fv_NewHire_DetailsForm.fn_ReturnControl_givenControlID("INSERT_txt_LastName");

In addition, I have found it helpful for this type of problem to preface the controls in the 'insertitemtemplate' with 'INSERT_", and controls in the 'edititemtemplate' with 'EDIT_" to quickly tell them apart in the debug output.

glenn garson
  • 416
  • 4
  • 7