如何从嵌套的内部控件中找到外部控件

时间:2009-09-03 03:24:10

标签: c# asp.net

我有以下嵌套结构。我需要的是根据RadioButtonList选择的值从后面的CustomControl1代码中过滤DB Linq查询。

x MainPage1 
x---- Panel1 (modal popup)
x--------- UpdatePanel (upMailOrStatusAction, on Panel1)
x-------------- RadioButtonList (rblActionLevel, on UpdatePanel)
x-------------- SubForm1 (on Panel1)
x------------------- CustomControl1 (on Subform1)
x------------------------ DropDownList (on CustomControl1)

我正在尝试使用以下内容来查找控件,但它说“当前上下文中不存在名称'upMailOrStatusAction'。

RadioButtonList rbl = upMailOrStatusAction.FindControl("rblActionLevel") as RadioButtonList;

找到RadioButtonList控件的最佳方法是什么?是的,我对此很新!

谢谢你, Jim在Suwanee,GA

好的,这是Popup aspx:

            <asp:Panel ID="pnlAddMailOrStatusAction" runat="server" CssClass="modalPopupLarge" Style="display: none;">
            <asp:UpdatePanel ID="upMailOrStatusAction" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="false" RenderMode="Block">
                <Triggers>
                    <asp:AsyncPostBackTrigger ControlID="rblActionType" />
                </Triggers>
                <ContentTemplate> 
                    <div class="borderDiv"> 
                        <table class="borderTable0" cellpadding="0" cellspacing="0" width="100%">
                            <thead>
                                <tr align="left">
                                    <th colspan="9">Action Detail</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr>
                                    <td colspan="1">
                                        <label class="labelfield">Action Level:</label>
                                    </td>
                                    <td colspan="1" rowspan="1" align="left">
                                        <asp:RadioButtonList ID="rblActionLevel" runat="server" AutoPostBack="True" RepeatDirection="Horizontal"
                                            RepeatLayout="Flow">
                                            <asp:ListItem Selected="True" Value="Base" Text="Base&nbsp;&nbsp;" />
                                            <asp:ListItem Value="Coverage" Text="Coverage" />
                                        </asp:RadioButtonList>
                                    </td>
                                    <td colspan="1" align="left">
                                        <asp:Label ID="lblMSCoverage" runat="server" class="labelfield" Text="Coverage:" />
                                    </td>
                                    <td colspan="1" align="left">
                                        <asp:Label ID="txtMSCoverage" runat="server" />
                                    </td>
                                    <td colspan="5">
                                        &nbsp;
                                    </td>
                                </tr>
                                <tr>
                                    <td colspan="9">
                                        <hr />
                                    </td>
                                </tr>
                                <tr>
                                   <td colspan="9">
                                    <st:MailAddSubform runat="server" ID="mailAddSubform" />
                                    <st:StatusActionAddSubform runat="server" ID="statusActionAddSubform" Visible="false" />
                                   </td>
                                </tr>
                                <tr>
                                    <td colspan="9">
                                        <hr />
                                    </td>
                                </tr> 
                            </tbody>    
                        </table>
                    </div>
                </ContentTemplate>
            </asp:UpdatePanel>
         </asp:Panel> 

这是子表单aspx:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MailAddSubform.ascx.cs" 
Inherits="Company.Solutions.Web.Controls.MailAddSubform" %>
                          行动:                                                                                 信息:                                              这是自定义控件aspx:                                                                                                                                                  过滤器                                                         

最后,这是自定义控件背后的代码。查找StackOverflow以查找单选按钮列表的位置:

using System;
using System.Collections.Generic;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using Company.Solutions.Data;
using Company.Solutions.Data.Model;
using Company.Solutions.Business.ViewModels;
using Company.Solutions.Business.Helpers;


namespace Comapny.Solutions.Web.Controls
{
    public partial class StMailActionLookup : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
           BindForm();
        }

        protected void BindForm()
        {
            IEnumerable actions = GetClaimMailActions(GetFilter());
            ddlLookup.DataSource = actions;
            ddlLookup.DataTextField = "CodeAndDescription";
            ddlLookup.DataValueField = "actionCd";
            ddlLookup.DataBind();
        }

        //protected void ddlLookup_DataBound1(object sender, System.EventArgs e)
        //{
        //    ddlLookup.Items.Insert(0, new ListItem("<Please Choose an Action>", String.Empty));
        //} 

        private MailActionFilters GetFilter()
        {
            MailActionFilters filters = new MailActionFilters();
            if (chkForms.Checked)
                    filters |= MailActionFilters.Forms;
            if (chkRequested.Checked)
                    filters |= MailActionFilters.RequestedInfo;
            if (chkOther.Checked)
                    filters |= MailActionFilters.Other;

            return filters;
        }

        public IEnumerable GetClaimMailActions(MailActionFilters filter)
        {
            RelationalDataContext db = RelationalDataContext.Create();
            List<Expression<Func<ClaimMailAction, bool>>> predicates = new List<Expression<Func<ClaimMailAction, bool>>>();

            const string MAIL_ACTIONS = "0";
            const char FORMS = 'F';
            const char REQUESTED_INFO = 'R';
            const char EXCLUDE = 'X';



            //StackOverflow help

            //RadioButtonList rbl = (RadioButtonList) Control.Parent.FindControl("rblActionLevel");




            if ((!chkForms.Checked && !chkRequested.Checked && !chkOther.Checked) | (chkForms.Checked && chkRequested.Checked && chkOther.Checked))
            {
                predicates.Add(cma => cma.ActionCd.StartsWith(MAIL_ACTIONS) && (cma.EsolutionsCode == null || cma.EsolutionsCode!= EXCLUDE));
            } else {

                if((filter & MailActionFilters.Forms) == MailActionFilters.Forms)
                    predicates.Add(cma => cma.ActionCd.StartsWith(MAIL_ACTIONS) && cma.EsolutionsCode == FORMS);

                if((filter & MailActionFilters.RequestedInfo) == MailActionFilters.RequestedInfo)
                    predicates.Add(cma => cma.ActionCd.StartsWith(MAIL_ACTIONS) && cma.EsolutionsCode == REQUESTED_INFO);

                if((filter & MailActionFilters.Other) == MailActionFilters.Other)
                    predicates.Add(cma => cma.ActionCd.StartsWith(MAIL_ACTIONS) && (cma.EsolutionsCode == null || (cma.EsolutionsCode != EXCLUDE && cma.EsolutionsCode != FORMS && cma.EsolutionsCode != REQUESTED_INFO)));
            }

            var predicate = PredicateBuilder.Make<ClaimMailAction>();
            predicates.ForEach(delegate(Expression<Func<ClaimMailAction, bool>> expr)
            {
                predicate = predicate.Or(expr);
            });

            var qry = db.ClaimMailActions.Where(predicate).Select(c => new { c.ActionCd, CodeAndDescription = string.Format("{0} - {1}", c.ActionCd, c.ActionDesc) });

            return qry.ToList();
        }
    }
}

新代码清单。我的同事用它来进行另一次查找。有人可以告诉我如何为这次查找做类似的事情吗?即使效率低下,如果它有效也是如此。

HtmlForm form;



        foreach(var ctl in Page.Controls[0].Controls)

        {

            if(ctl is HtmlForm)

            {

                form = ctl as HtmlForm;

                ContentPlaceHolder holder = form.FindControl("DefaultContent") as ContentPlaceHolder;

                if (holder != null)

                {

                   PlaceHolder paymentControlHolder = holder.FindControl("plcPaymentForm") as PlaceHolder;

                    if (paymentControlHolder != null)

                    {

                        IListener listener;

                        foreach (var c in paymentControlHolder.Controls)

                        {

                            if (c is IListener)

                            {

                                listener = c as IListener;

                                rblPaymentType.SelectedIndexChanged += listener.AddHandler();

                            }

                        }

                    }

                }





            }

        }

好的,我正在尝试这个,但还没有弄清楚如何确定单选按钮的选定值:

HtmlForm form;
        foreach (var ctl in Page.Controls[0].Controls) { 
            if (ctl is HtmlForm) { 
                form = ctl as HtmlForm; 
                ContentPlaceHolder holder = form.FindControl("DefaultContent") as ContentPlaceHolder; 
                if (holder != null) {
                    RadioButtonList rblControlHolder = holder.FindControl("rblActionLevel") as RadioButtonList; 
                    if (rblControlHolder != null) { 

                    }
                }
            }
        }

5 个答案:

答案 0 :(得分:2)

我不确定我是否完全理解你想要实现的目标。但是如果你想在你的页面上找到一个控件,你可能需要一个解决方案,因为我发布了here

 public static Control FindControlRecursive(Control parent, string controlId)
 {
     if (controlId == parent.ID)
         return parent;

     foreach (Control ctrl in parent.Controls)
     {
         Control tmp = FindControlRecursive(ctrl, controlId);
         if (tmp != null)
             return tmp;
     }

     return null;
 }

它是标准查找控件的递归实现。但明智地选择你的父母。如果您有一个大页面并且您指示它是搜索根,那么它将遍历页面的所有控件,直到最深的嵌套控件。您也可以采取相反的方式,基本上从您的控件开始,递归上升,直到您达到页面级别。将是另一种选择。

我发现这个递归查找的唯一问题是在页面上有转发器时可能会遇到问题。你不应该遍历转发器的内部控件。由于它的架构存在一些问题,否则它将失去它的观点。一旦我有时间,我将发布这种递归方法的更新。

编辑:
您将获得单选按钮的选定条目,如下所示:

RadioButtonList myInstance = //find my radio button list
string selectedValue = myInstance.SelectedValue;

答案 1 :(得分:0)

使用属性Parent启动控制树。

CustomControl1.Parent.Parent.Parent.FindControl("rblActionLevel");

答案 2 :(得分:0)

混沌捎带......

RadioButtonList rbl = (RadioButtonList)Control.Parent.FindControl("rblActionLevel")

答案 3 :(得分:0)

  

“非静态字段,方法或属性'System.Web.UI.Control.Parent.Get'需要对象引用使用以下内容:RadioButtonList rbl =(RadioButtonList)StMailActionLookup.Parent.FindControl(” rblActionLevel“);

当您引用“mailActionLookup”(控件实例的ID)时,引用对象类型“StMailActionLookup”。

所以代码看起来像:

RadioButtonList rbl = (RadioButtonList) mailActionLookup.Parent.FindControl("rblActionLevel");

不确定这是你提出的代码的问题,但只是一个小小的修正。

另外,请记住,UpdatePanel是一个模板控件,而RadioButtonList和所有其他控件都在UpdatePanels生命周期的某个地方的ContentTemplateContainer中呈现(我认为它在CreateChildControls附近)。这取决于你的BindForm()方法的调用位置,但可能是当你试图找到它时,RadioButtonList真的不可用。即使它在标记中,模板中的控件也不会像标记中的其他控件一样创建。他们是一种奇怪的野兽。

对于测试,尝试在重写的Render方法中运行find控制代码或类似的方法。通过Render方法,您可以保证所有控件都可用。

public override Render(HtmlTextWriter writer) {
   RadioButtonList rbl = (RadioButtonList)upMailOrStatusAction.FindControl("rblActionLevel");
}

此外,由于upMailOrStatusAction是一个UpdatePanel,代码可能是

upMailOrStatusAction.ContentTemplateContainer.FindControl("rblActionLevel");

答案 4 :(得分:0)

好的,感谢大家的帮助,最终得到了这个工作。感谢JayRu指导我正确的方向。这是我正在使用的东西(它仍然需要一些工作来连接它):

HtmlForm form;
        foreach (var ctl in Page.Controls[0].Controls) { 
            if (ctl is HtmlForm) { 
                form = ctl as HtmlForm; 
                ContentPlaceHolder holder = form.FindControl("DefaultContent") as ContentPlaceHolder; 
                if (holder != null) {
                    RadioButtonList rblControlHolder = holder.FindControl("rblActionLevel") as RadioButtonList; 
                    if (rblControlHolder != null) {
                        if (rblControlHolder.SelectedValue == "Base") {

                        }
                    }
                }
            }
        }