2009-09-03 3 views
0

У меня есть следующая вложенная структура. Мне нужно отфильтровать запрос DB Linq из кода CustomControl1, основываясь на значении выбора RadioButtonList.Как найти внешний контроль из вложенного внутреннего управления

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 Да, я довольно новый с этим

Спасибо, Джим в Suwanee, GA

Ok, Вот 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) { 

        } 
       } 
      } 
     } 

ответ

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

Это рекурсивная реализация стандартного средства поиска. Но разумно выбирайте своих родителей. Если у вас есть большая страница, и вы указываете, что это корень поиска, тогда она будет перемещаться по всем элементам управления страницы до самого глубокого вложенного элемента управления. Вы также можете пойти обратным способом, в основном, начиная с вашего контроля и рекурсивно подниматься до уровня страницы. Будет другой вариант.

Единственная проблема, с которой я столкнулся с этой рекурсивной находкой, заключается в том, что у вас могут возникнуть проблемы при использовании ретранслятора на вашей странице. Вы не должны проходить внутренние органы управления ретранслятора. Из-за своей архитектуры есть некоторые проблемы, которые в противном случае потеряют его viewstate. Как только у меня будет время, я опубликую обновление этого рекурсивного метода.

Edit:
Вы получаете выбранную запись кнопки радио следующим образом:

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

Juri, Цель состоит в том, чтобы определить значение переключателя, чтобы я мог изменить свой запрос, чтобы заполнить выпадающий список соответственно. Я попробую ваш поиск, а также может пригодиться. Спасибо! Jim – James

+0

хорошо, если ваш radioobuttonlist находится на вашем пользовательском контроле или странице, у вас должен быть прямой доступ к нему, не так ли? Или, по крайней мере, это элемент контейнера. Я действительно не понимаю, зачем вам тратить все с вашей страницы вниз. – Juri

+0

Btw, код ниже можно было бы решить, вызвав мой FindControlRecursive (this.Page, "rblActionLevel") как RadioButtonList, хотя я все еще убежден, что есть очень простой способ. – Juri

0

Используйте свойство Parent, чтобы сделать свой путь управления дерево.

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

Ok ребята, я получаю эту идею, но я в коде позади от таможенного контроля, который определяется, как это: общественный частичный класс StMailActionLookup: System.Web.UI.UserControl И я получаю «Ссылку на объект требуется для нестатических полей, методы или свойств„System.Web.UI.Control.Parent.Get“ Используя следующее: RadioButtonList rbl = (RadioButtonList) StMailActionLookup.Parent.FindControl («rblActionLevel»); – James

+0

Так настраивается пользовательский элемент управления внутри подформы:

James

+0

Почему бы вам не опубликовать всю свою форму, чтобы мы могли проанализировать структуру. – ChaosPandion

0

Спекуляция на Хаосе ...

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

«Ссылка на объект необходим для не-статического поля, метода или свойства«System.Web.UI.Control.Parent. Get»Используя следующее: RadioButtonList руб = (RadioButtonList) StMailActionLookup.Parent.FindControl ("rblActionLevel");

вы ссылаться на тип объекта "StMailActionLookup", когда вы должны ссылаться на«почта ActionLookup ", идентификатор экземпляра элемента управления.

Так что код будет выглядеть следующим образом:

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

Не уверен, что это проблема с кодом вы придумали, однако, лишь небольшая коррекция.

Кроме того, помните, что UpdatePanel - это шаблонный элемент управления, а RadioButtonList и все остальные элементы управления отображаются внутри его ContentTemplateContainer где-то в жизненном цикле UpdatePanels (я думаю, что это где-то вокруг CreateChildControls). Это зависит от того, откуда вызывается метод BindForm(), но может быть, что RadioButtonList действительно недоступен в то время, когда вы пытаетесь его найти. Даже если его в разметке, элементы управления в шаблоне не создаются так же, как другие элементы управления в разметке. Они странные звери.

Для проверки попробуйте запустить управляющий код find в переопределенном методе Render или что-то в этом роде. По методу Render вам гарантировано, что все элементы управления будут доступны.

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

Кроме того, поскольку upMailOrStatusAction является UpdatePanel, код может быть

upMailOrStatusAction.ContentTemplateContainer.FindControl("rblActionLevel"); 
+0

Для вашего первого примера кода «mailActionLookup» и второго примера «upMailOrStatusAction» я получаю ошибку «имя не существует в текущем контексте» с каждой ошибкой, ссылающейся на поле в кавычках здесь. Я еще не пробовал Render, но я это сделаю. Спасибо, Jim – James

+0

Да, извините, я должен был внимательно прочитать код. MailActionLookup является братом RadioButtonList (полностью пропустил это), поэтому писать хрупкий код очень сложно. Лучше всего начинать страницу и выполнять рекурсивный поиск по иерархии для radioobuttonlist. PageFindControl не будет делать трюк, потому что он идет только на один уровень. Вам нужно найти вспомогательный метод в Интернете. Или вы можете использовать вспомогательный метод, который начинается с mailActionControl и поднимается вверх по иерархии, просматривая коллекцию элемента управления каждого родительского элемента управления. Оба они довольно неэффективны. – JayRu

+0

Интересно, могу ли я установить переменную сеанса на основе выбора переключателя и прочитать это значение здесь? Должен быть более простой способ! Спасибо, Jim – James

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

         } 
        } 
       } 
      } 
     } 
+0

Если JayRu поставит вас на путь поиска решения, возможно, вы должны принять его ответ. Или, по крайней мере, проголосуйте за него (если у вас достаточно голосов, чтобы проголосовать ... не знаю) –