ASP.Net PlaceHolder、PanelなどのコントロールがINamingContainerを実装していないため、FindControlが無効になります

2068 ワード

コードは次のとおりです.
 
  
Panel spnButtons = new Panel();
Button btn = new Button();
btn.ID = "btn1";
spnButtons.Controls.Add(btn);
// True,
Response.Write(spnButtons.FindControl(btn.ID) == null);

次のコードでいいです.
 
  
Panel spnButtons = new Panel();
Page.Controls.Add(spnButtons);// Panel Page

Button btn = new Button();
btn.ID = "btn1";
spnButtons.Controls.Add(btn);
// False,
Response.Write(spnButtons.FindControl(btn.ID) == null);

あるいはRepeaterを使ってもいいです.
 
  
Repeater spnButtons = new Repeater();

Button btn = new Button();
btn.ID = "btn1";
spnButtons.Controls.Add(btn);
// False,
Response.Write(spnButtons.FindControl(btn.ID) == null);

PanelがWebControlに継承されていることを調べたが、WebControlの定義は:
public class WebControl : Control, IAttributeAccessor
{}
Repeaterの定義は次のとおりです.
public class Repeater : Control, INamingContainer
{}
まさかRepeaterがINamingContainerを実現したからでしょうか?
またクラスをカスタマイズし、パネルから継承し、INamingContainerを実現しました.コントロールを見つけることができます.
 
  
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
myPanel spnButtons = new myPanel();

Button btn = new Button();
btn.ID = "btn1";
spnButtons.Controls.Add(btn);

Response.Write(spnButtons.FindControl(btn.ID) == null);
}


}

public class myPanel : Panel, INamingContainer
{
public myPanel():base()
{
}
}

上、ASP.Netでは、PlaceHolder、PanelなどのコントロールでINamingContainerが実装されておらず、FindControlが無効になっています
これらのコントロールをINamingContainerを実装した親コントロールに加えたり、サブクラスでINamingContainerを実装したりすれば、FindControlを有効にすることができます.