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

我有以下嵌套结构。 我需要的是根据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:

        
Action Detail
 


这是子表单aspx:

  

操作:消息:这是自定义控件aspx:Filters

最后,这是自定义控件背后的代码。 查找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("", 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>> predicates = new List<Expression<Func>>(); 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(); predicates.ForEach(delegate(Expression<Func> 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) { } } } } 

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

  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; 

使用属性Parent来启动控制树。

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

抄袭混沌……

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

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

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

所以代码看起来像:

 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"); 

好的,最后得到了这个工作感谢大家的帮助。 感谢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") { } } } } }