简体   繁体   中英

How to access controls inside an XML object/control using C#/ASP.NET?

I'm new to XML/XSLT. What I did is I've created an XML file with some list, and used XSLT to transform it.

Here's the code:

protected void Page_Load(object sender, EventArgs e)
{
    this.form1.Controls.Add(Xml1);

    Button btnSubmit = new Button();
    btnSubmit.Text = "Submit";
    this.form1.Controls.Add(btnSubmit);
    btnSubmit.Click += new System.EventHandler(btnSubmit_Click);

    Xml1.DocumentSource = "~/xml/XML_F52E2B61-18A1-11d1-B105-00805F49916B1.xml";
    Xml1.TransformSource = "~/KPI_table.xslt";

    //Together, the Xml1.DocumentSource and the Xml1.TransformSource will display a 
    //list of items with a dropdownlist each.
}

private void btnSubmit_Click(Object sender, System.EventArgs e)
{
    foreach (Control c in form1.Controls) //or is it possible to access the controls
                                          //inside XML1 here?
    {
         //This is where I need to access the controls inside the Xml1 object.
    }
}

When I tried to debug/trace the program, I found out that the foreach loop only saw 3 controls ( System.Web.UI.LiteralControl , System.Web.UI.WebControls.Xml , and System.Web.UI.WebControls.Button ). And I can't find a way to get into the controls inside the XXML object/control so I can get the SelectedValue of the DropdownLists/options. How will I be able to access the controls inside the Xml1 object/control??

Update 2: Here is the generated HTML code :

<body>
    <form method="post" action="Main.aspx" id="form1">
      <div class="aspNetHidden">
        <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"     value="/wEPDwULLTE2MTY2ODcyMjlkZCn80c6JtFOE8ISKTFArpEqY4qC8tA9LkNAs7gn6n6Zu" />
     </div>    
   <div class="aspNetHidden">    
      <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgLm9oEzAqDAiY0LmVXxKZ8kddyJnX1LgEhJf4qGDJE14PdWmMUYC7LLAAk=" />
   </div>
   <div>
   </div>
   <table id="tbl1" runat="server" xmlns:asp="remove">    
     <tr>
       <td>BEHAVIOR</td>
     </tr>
     <tr>
       <td>Stellar KPIs</td>
     </tr>
     <tr>    
       <td>Customer Demeanor at Start of call:</td>
       <td>
         <select id="ddl_3" runat="server" AutoPostBack="true"    onchange="getvalue(this);">
           <option value="0">Select</option>
           <option value="A">                Audibly Happy</option>
           <option value="N">                Neutral</option>    
           <option value="I">                Irate</option>
           <option value="R">                At risk</option>
        </select>
      </td>
    </tr>
    <tr>
    <td>Customer Demeanor at End of call:</td>    
    <td>
      <select id="ddl_8" runat="server" AutoPostBack="true" onchange="getvalue(this);">
        <option value="0">Select</option>
        <option value="A">                Audibly Happy</option>
        <option value="N">                Neutral</option>
        <option value="I">                Irate</option>    
        <option value="R">                At risk</option>
      </select>
    </td>
  </tr>

Update 3: here's the screenshot of the HTML code rendered: screenshot

Update 4: here's the XSLT file

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:asp="remove" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="html" indent="yes"/>
    <xsl:template name="home" match="/">
        <table id="tbl1" runat="server">
            <xsl:for-each select="ProgramKPI/KPIs">
                <xsl:variable name="varKPI" select="KPI_ID"/>
                <xsl:choose>
                    <xsl:when test="Level = '1'">
                        <tr>
                            <td>
                                <xsl:value-of select="Attribute"/>
                            </td>
                        </tr>
                    </xsl:when>
                    <xsl:when test="Level = '2'">
                        <tr>
                            <td>
                                <xsl:value-of select="Attribute"/>
                            </td>
                        </tr>
                    </xsl:when>
                    <xsl:when test="Level = '3'">
                        <tr>
                            <td>
                                <xsl:value-of select="Attribute"/>
                            </td>
                            <xsl:variable name="ddl_name" select="concat('ddl_', KPI_ID)"/>
                            <td>
                                <xsl:element name="select">
                                    <xsl:attribute name="id"><xsl:value-of select="concat('ddl_', KPI_ID)"/></xsl:attribute>
                                    <xsl:attribute name="runat">server</xsl:attribute>
                                    <xsl:attribute name="AutoPostBack">true</xsl:attribute>
                                    <xsl:attribute name="onchange">getvalue(this);</xsl:attribute>
                                    <xsl:element name="option">
                                        <xsl:attribute name="value"><xsl:value-of select="0"/></xsl:attribute>
                                        <xsl:value-of select="'Select'"/>
                                    </xsl:element>
                                    <xsl:for-each select="//Parent_KPI[.=$varKPI]">
                                        <xsl:element name="option">
                                            <xsl:attribute name="value"><xsl:value-of select="preceding-sibling::AttributeCode"/></xsl:attribute>
                                            <xsl:value-of select="preceding-sibling::Attribute"/>
                                        </xsl:element>
                                    </xsl:for-each>
                                </xsl:element>
                                <!--<asp:DropDownList id="{concat('ddl_', KPI_ID)}" runat="server">
                        <asp:ListItem value="0">  Select  
                        </asp:ListItem>

                        <xsl:for-each select="//Parent_KPI[.=$varKPI]">
                          <asp:ListItem>
                            <xsl:attribute name="value">
                              <xsl:value-of select="preceding-sibling::AttributeCode"/>
                            </xsl:attribute>
                            <xsl:value-of select="preceding-sibling::Attribute"/>
                          </asp:ListItem>
                        </xsl:for-each>
                      </asp:DropDownList>-->
                            </td>
                        </tr>
                    </xsl:when>
                </xsl:choose>
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>

This won't work.

Text like <asp:DropDownList/> need to be interpreted by ASP.NET in order to be treated as controls. You're just sending that text to the browser.

Try checking for child controls. Ideally you'd do this recursively but as a quick and dirty way:

private void btnSubmit_Click(Object sender, System.EventArgs e)
{
    foreach (Control c in form1.Controls) 
    {            
        if (c.HasControls())
        {
            foreach (Control child in c)
            {
                //Access Child controls here
            }
        }
    }
}

That being said I'm unsure of adding controls to the page via XML this way.

Also you may want to add the controls earlier in the page lifecycle possibly the onInit event and make sure to not add the controls again on postback.

UPDATE: In light of John Sanders answer: you could go old school and use the request object to access values, not a .net but it should work. Eg:

string dropDownValue = Request.Form["yourDropDownID"];

Update 2 To Iterate through the values posted back you can do the following:

private void btnSubmit_Click(Object sender, System.EventArgs e)
{
    foreach (string key in Request.Form.AllKeys)
    {
        Response.Write (string.Format("{0} => {1}<br />", key, request.Form[key]));
    }
}

However, to do this you will need to make sure that the rendered HTML has a name attribute for the form elements. Change your XSLT for the select element to the following:

<xsl:element name="select">
   <xsl:attribute name="id">
      <xsl:value-of select="concat('ddl_', KPI_ID)"/>
   </xsl:attribute>
   <xsl:attribute name="name">
      <xsl:value-of select="concat('ddl_', KPI_ID)"/>
   </xsl:attribute>
   <xsl:attribute name="onchange">getvalue(this);</xsl:attribute>
   <xsl:element name="option">
      <xsl:attribute name="value">
         <xsl:value-of select="0"/>
      </xsl:attribute>
      <xsl:value-of select="'Select'"/>
</xsl:element>

Note the inclusion of the name attribute and the removal of the runat server and auto postback attributes.

You say that the XML and transform produce a list of dropdown lists - are they plain html tags, or does it create asp.net controls?

I seem to remember that you can only access controls from code-behind if they have an ID property and runat="server" set in the tag.

If they are plain html, can you influence the transform so that it includes an ID and runat="server" when it is applied to the xml, or is the transform out of your control?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM