【问题标题】:How to access controls inside an XML object/control using C#/ASP.NET?如何使用 C#/ASP.NET 访问 XML 对象/控件中的控件?
【发布时间】:2011-04-13 08:56:20
【问题描述】:

我是 XML/XSLT 的新手。我所做的是创建了一个带有一些列表的 XML 文件,并使用 XSLT 对其进行了转换。

代码如下:

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.
    }
}

当我尝试调试/跟踪程序时,我发现 foreach 循环只看到 3 个控件(System.Web.UI.LiteralControlSystem.Web.UI.WebControls.XmlSystem.Web.UI.WebControls.Button)。而且我找不到进入 XXML 对象/控件内部控件的方法,因此我可以获得 DropdownLists/options 的SelectedValue。我如何才能访问 Xml1 对象/控件中的控件??

更新 2:这是生成的 HTML 代码

<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>

更新 3:这是呈现的 HTML 代码的屏幕截图: screenshot

更新 4:这是 XSLT 文件

<?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>

【问题讨论】:

  • 不是关于 XSLT(您可以通过任何其他方式生成该列表),而是动态生成的控件。重新标记。
  • 如果您认为需要一张图片来解释自己,您可以使用免费的图片托管服务之一(如imgur)上传图片,并在您的问题中添加指向它的链接.
  • 您不需要删除&lt; &gt;。只需选择 XML 块并按 {} 图标或 Control-K。

标签: c# .net asp.net xml


【解决方案1】:

这行不通。

&lt;asp:DropDownList/&gt; 这样的文本需要被 ASP.NET 解释才能被视为控件。您只是将该文本发送到浏览器。

【讨论】:

    【解决方案2】:

    尝试检查子控件。理想情况下,您会递归地执行此操作,但这是一种快速而肮脏的方式:

    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
                }
            }
        }
    }
    

    话虽如此,我不确定是否可以通过这种方式通过 XML 向页面添加控件。

    此外,您可能希望在页面生命周期的早期添加控件,可能是 onInit 事件,并确保在回发时不再添加控件。

    更新:根据约翰·桑德斯的回答: 你可以去老学校并使用请求对象来访问值,而不是.net,但它应该可以工作。例如:

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

    更新 2 要遍历回发的值,您可以执行以下操作:

    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]));
        }
    }
    

    但是,要做到这一点,您需要确保呈现的 HTML 具有表单元素的名称属性。将选择元素的 XSLT 更改为以下内容:

    <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>
    

    注意包含 name 属性以及删除 runat server 和 auto postback 属性。

    【讨论】:

    • @John P :当你说我“可以去老学校并使用请求对象来访问值,而不是.net ...”时,这是否意味着我必须输入代码string dropDownValue = Request.Form["yourDropDownID"];在javascript中?
    • @Rome,此代码仍将进入您的 btnSubmit_Click 处理程序服务器端。 “yourDropDownID”是呈现到 HTML 控件中的 ID。此方法使用回传到服务器的 HTTP 请求。您还可以遍历 request.form 对象,我会看看是否可以在我的答案中获得一些代码。老派,我的意思是指在.net之前如何在经典asp中完成此用途。
    • @John P :哦,请。我很感激。 :) 作为对您之前的回答的回应,我尝试了 c.HasControls() 但它看不到 XML 对象/控件中的子控件。
    • @John P:感谢更新 2。我试过了,这是单击提交按钮后页面上显示的内容:__VIEWSTATE =&gt; /wEPDwULLTE2MTY2ODcyMjlkZCn80c6JtFOE8ISKTFArpEqY4qC8tA9LkNAs7gn6n6Zu __EVENTVALIDATION =&gt; /wEWAgLm9oEzAqDAiY0LmVXxKZ8kddyJnX1LgEhJf4qGDJE14PdWmMUYC7LLAAk= ctl03 =&gt; Submit 这是正确的吗?我需要做任何其他特殊的事情来从 ViewState 中获取值吗?
    • 您可以编辑您的问题以包含呈现的 HTML 的示例吗?这会有所帮助。
    【解决方案3】:

    您说 XML 和转换生成下拉列表列表 - 它们是纯 html 标记,还是创建 asp.net 控件?

    我似乎记得,如果控件具有 ID 属性并在标记中设置了 runat="server",则您只能从代码隐藏中访问控件。

    如果它们是纯 html,您能否影响转换,使其在应用于 xml 时包含 ID 和 runat="server",或者转换不受您的控制?

    【讨论】:

    • 它们不是普通的 html 标签。我使用 XSLT 创建了控件。 &lt;xsl:element name="select"&gt; &lt;xsl:attribute name="id"&gt; &lt;xsl:value-of select="concat('ddl_', KPI_ID)"/&gt; &lt;/xsl:attribute&gt; &lt;xsl:attribute name="runat"&gt;server &lt;/xsl:attribute&gt; &lt;/xsl:element&gt;
    • 我创建的控件中包含“runat=server”属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-19
    • 1970-01-01
    • 2013-11-09
    相关资源
    最近更新 更多