2009-04-08 7 views
8

2レベルのネストされたマスターページがあります。それにはマスターページがあり、そのマスターページにはマスターページがあります。ネストされたマスターページ内でのコントロールの検索

私は名前を「BCR」とのContentPlaceHolderのコントロールスティック - 私はそうのようなコントロールを見つけなければならない:

Label lblName =(Label)Master.Master.FindControl("bcr").FindControl("bcr").FindControl("Conditional1").FindControl("ctl03").FindControl("lblName"); 

は、私は完全に失われたのですか?それとも、これはどのように行う必要がありますか?

私は、条件付きコンテンツコントロールの中にあるMultiViewを使用しようとしています。だから私はビューを変更したい場合、私はそのコントロールの権利への参照を取得する必要がありますか?その参考資料を入手することは、さらに厄介なものになるでしょう!より良い方法がありますか?

おかげ

答えて

4

はまず、あなたはMasterPagesが実際にページ内に座っていることを知っている必要があります。あなたのASPXのLoadイベントの後にMasterPageのLoadイベントが実際に呼び出されるように。

これは、実際にはPageオブジェクトがコントロール階層内の最も高いコントロールであることを意味します。

このように、ネストされた環境でコントロールを見つける最良の方法は、探しているものが見つかるまで、すべてのコントロールと子コントロールをループする再帰関数を作成することです。この場合、マスターページは実際にはメインページコントロールの子コントロールです。

あなたはこのような任意のコントロールの内側からメインページオブジェクトを取得:

のC#:

this.Page。

VB.NET

Me.Page

私は的環境は常にネストされているとして、通常は、コントロールのクラスにFindControl()メソッドは、かなり無用であることがわかります。

この場合、.NETの3.5の新しい拡張機能を使用してControlクラスを拡張することにしました。あなたのAppCodeフォルダ、と言うには、コードの下(VB.NET)を使用することにより

、すべてのコントロールは今FindByControlIDを呼び出すことにより、再帰的な検索をpeformます()

Public Module ControlExtensions 
    <System.Runtime.CompilerServices.Extension()> _ 
    Public Function FindControlByID(ByRef SourceControl As Control, ByRef ControlID As String) As Control 
     If Not String.IsNullOrEmpty(ControlID) Then 
      Return FindControlHelper(Of Control)(SourceControl.Controls, ControlID) 
     Else 
      Return Nothing 
     End If 
    End Function 

    Private Function FindControlHelper(Of GenericControlType)(ByVal ConCol As ControlCollection, ByRef ControlID As String) As Control 
     Dim RetControl As Control 

     For Each Con As Control In ConCol 
      If ControlID IsNot Nothing Then 
       If Con.ID = ControlID Then 
        Return Con 
       End If 
      Else 
       If TypeOf Con Is GenericControlType Then 
        Return Con 
       End If 
      End If 

      If Con.HasControls Then 
       If ControlID IsNot Nothing Then 
        RetControl = FindControlByID(Con, ControlID) 
       Else 
        RetControl = FindControlByType(Of GenericControlType)(Con) 
       End If 

       If RetControl IsNot Nothing Then 
        Return RetControl 
       End If 
      End If 
     Next 

     Return Nothing 
    End Function 

End Module 
22

検索コントロールの痛みであり、私は空のIDが渡された場合はnullを返します単一の変更で、私はかなりしばらく前にCodingHorror blogからもらったこの方法を使用してきた。

/// <summary> 
/// Recursive FindControl method, to search a control and all child 
/// controls for a control with the specified ID. 
/// </summary> 
/// <returns>Control if found or null</returns> 
public static Control FindControlRecursive(Control root, string id) 
{ 
    if (id == string.Empty) 
     return null; 

    if (root.ID == id) 
     return root; 

    foreach (Control c in root.Controls) 
    { 
     Control t = FindControlRecursive(c, id); 
     if (t != null) 
     { 
      return t; 
     } 
    } 
    return null; 
} 

をあなたのケースでは、私はあなたが必要と思います以下:

,

このメソッドを使用すると、コントロールがどこにあるのかを正確に知る必要がないので(通常、IDを知っていると仮定して)、はるかに便利です。同じ名前、あなたはおそらくいくつかの奇妙な行動を取るので、それは気を付けるべきことかもしれません。

+0

これは完全に機能します。ありがとう。 –

+0

+1これもまた助けてくれました – leen3o

+0

+1これは5歳のようなものですが、この方法は私に頭痛を救った、ありがとう! – psoshmo

4

私は再帰が大好きですが、andyとMunに同意しますが、あなたが検討したいかもしれないもう1つのアプローチはstrongly typed Master pageです。あなたがしなければならないのは、あなたのaspxページに1つの指令を追加することだけです。

マスターページからページのコントロールにアクセスする代わりに、ページ自体からマスターページ内のコントロールにアクセスすることを検討してください。このアプローチは、マスターページにヘッダーラベルがあり、マスターを使用する各ページからその値を設定したいときには非常に意味があります。

私は100%確信していませんが、ネストされたマスターページでは、アクセスするコントロールを含むマスターにVirtualPathをポイントするだけで簡単なテクニックになると思います。ただし、それぞれのマスターページに1つずつ、2つのコントロールにアクセスする必要がある場合は、難しいかもしれません。

+0

うん、良い点。場合によっては、カスタムページベースのある種のメソッドやプロパティにその機能を追加するだけでよい場合もあります。もちろん、再帰的な制御ファインダを組み込んでいることに傷つくことはありませんが – andy

1

私は<%@ MasterType VirtualPath="~/MyMaster.master" %>メソッドを使用しました。私はマスターマスターページにプロパティを持っていますし、マスターマスタープロパティを呼び出す同じ名前の詳細マスターページの他のプロパティで、正常に動作します。

私は、このエラーメッセージを表示する必要があるだけdiv要素である

public string MensajeErrorString 
    { 
     set 
     { 
      if (value != string.Empty) 
      { 
       MensajeError.Visible = true; 
       MensajeError.InnerHtml = value; 
      } 
      else 
       MensajeError.Visible = false; 
     } 


    } 

メインマスターページでこれを持っています。私は詳細マスターページ(これはメインマスターと入れ子になっています)のページでこの同じプロパティを使用したいと思います。

次に詳細マスタに私はこの

public string MensajeErrorString 
    { 
     set 
     { 
       Master.MensajeErrorString = value; 
     } 

    } 

Imは同じ動作を作成するために、詳細マスタからメインマスタープロパティを呼び出しています。

0

私はちょうどそれが完全に働いている。 contentpage.aspxで

、私は次のように書いた:ここ

If Master.Master.connectsession.IsConnected Then my coded comes in here End If

2

は、より汎用的で、カスタム条件で動作するコード(!それは、ラムダ式を指定できます)

ですコール:

Control founded = parent.FindControl(c => c.ID == "youdId", true); 

コントロール拡張

public static class ControlExtensions 
{ 
    public static Control FindControl(this Control parent, Func<Control, bool> condition, bool recurse) 
    { 
     Control founded = null; 
     Func<Control, bool> search = null; 
     search = c => c != parent && condition(c) ? (founded = c) != null : 
                recurse ? c.Controls.FirstOrDefault(search) != null : 
                (founded = c.Controls.FirstOrDefault(condition)) != null; 
     search(parent); 
     return founded; 
    } 
} 
関連する問題