0

特定のページのコントロールコレクションを動的にロードするメソッドを作成しようとしています。これにより、ページを反復処理して、ページに存在する特定のタイプのコントロールのリストを作成できます。特定のページクラスから継承するページについて、特定の属性を持つ編集可能なフィールドのリストをコンパイルしたいという考え方です。これはすべて、これらのページの外部(ユーザーがこれらの他のページを管理できるようにする別のページ)で発生します。

次の両方のシナリオを試しました。

BasePage page = (BasePage)System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(string.Format("~/Pages/{0}/Manage.aspx", type.ToString()), typeof(BasePage));

IHttpHandler handler = PageParser.GetCompiledPageInstance(string.Format("~/Pages/{0}/Manage.aspx", type.ToString()), Context.Server.MapPath(string.Format("~/Pages/{0}/Manage.aspx", type.ToString())), HttpContext.Current);
BasePage page = handler as BasePage;

どちらの状況でも、ページ変数は開始されますが、コントロールコレクションは空白です。おそらく、これらのメソッドは両方とも、マークアップではなくコードビハインドのみをロードしているためです。ページのコントロールコレクションを動的にロードするにはどうすればよいですか?

4

3 に答える 3

0

ページのライフサイクルを台無しにすることはありません。ASP.NETに独自にコントロール階層を管理させ、再帰ロジックを使用してページ上のコントロールを検査します。

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        FindPanelControls(Page);
    }
}

private void FindPanelControls(Control ctrl)
{
    if (ctrl.HasControls())
    {
        foreach (var childCtrl in ctrl.Controls.OfType<WebControl>())
        {
            //check for certain attributes
            if (childCtrl is Panel)
                Response.Write(childCtrl.ID);

            //recursively call the function for this control
            FindPanelControls(childCtrl);
        }
    }
}
于 2012-04-04T21:32:41.957 に答える
0

あなたはそれを複雑にしすぎています。Page.Controlsコレクションを再帰的にループし、関心のあるコントロールのタイプを確認するだけです。これらの以前の質問を見てください。

ASP.Net / C#、ページ上の特定のコントロールをループしますか?

asp.netWebページのすべてのコントロールをループします

于 2012-04-04T21:32:54.297 に答える
0

実行時にページBからページAのコントロールを評価する必要があるというまったく同じ要件に遭遇しました。

ページのライフサイクルを実行するために必要な追加の手順が1つあります。Page.ProcessRequest()メソッドを呼び出す必要があります。Page.ProcessRequestメソッド(MSDN)。このメソッドはIntellisenseから隠されています。

この後、ページのコントロールにアクセスできるようになります。

Page page = (Page)BuildManager.CreateInstanceFromVirtualPath("~/MyPage.aspx", typeof(Page));
page.ProcessRequest(HttpContext.Current);

ページにマスターページがある場合は、マスターページのプレースホルダーを掘り下げる必要があります。

ただし、Microsoftの発言に注意してください。

「このメソッドを呼び出さないでください。」

「このAPIは.NETFrameworkインフラストラクチャをサポートしており、コードから直接使用することを目的としたものではありません。

これを行うことによる悪影響があるかどうかはまだわかりません。


編集:ページ内でページを実行すると、無数の問題が発生する可能性があるため、少し異なる方向に進みました。

HTML Agility Packを使用すると、*。aspxファイルをロードして、そのノードを非常に簡単に再帰的にトラバースできます。たとえば、ページ上のすべてのaspボタンを検索する場合:

private static void FindAllButtonControls(HtmlNodeCollection htmlNodeCollection, List<HtmlNode> controlNodes)
{
    foreach (HtmlNode childNode in htmlNodeCollection)
    {
        if (childNode.Name.Equals("asp:button"))
        {
            controlNodes.Add(childNode);
        }
        else
        {
            FindAllButtonControls(childNode.ChildNodes, controlNodes);
        }
    }
}

public static List<HtmlNode> FindButtonControlsAtVirtualPath(String path)
{
    HtmlAgilityPack.HtmlDocument aspx = new HtmlAgilityPack.HtmlDocument();

    aspx.OptionFixNestedTags = true;
    aspx.Load(HttpContext.Current.Server.MapPath(path));

    List<HtmlNode> controlNodes = new List<HtmlNode>();
    FindAllButtonControls(aspx.DocumentNode.ChildNodes, controlNodes);

    return controlNodes;
}
于 2013-10-16T05:33:33.340 に答える