2009-09-18 3 views
6

を通じてマスターページで関数を呼び出しますが、どのように私は、ユーザーコントロールのためにそれを呼んでください:ASP.NET:前方かなりstraigtあるページでマスターページから関数を呼び出すと、ユーザーコントロール

<%@ MasterType VirtualPath="~/MasterPage.master" %>の追加、ユーザーコントロール上では動作しません。

だからthis.Page.Master.MyFunction()は失敗:(

答えて

7

ニルス、(JDunkerleyによって示唆されるように)

レバレッジ反射が問題に対する1つのアプローチです。

  1. メソッドを含むインターフェイスを作成することも考えられます。
  2. マスターページでインターフェイスを実装する
  3. コントロールから、this.Page.Masterのインターフェイスタイプを参照してください。
  4. メソッドを呼び出します。

これはより優れたOOアプローチであり、結合が少なくなり、実行時の反映よりも優れたパフォーマンスを発揮します。

こちらがお役に立てば幸いです。

+0

私はこのアプローチを使用し、うまくいきました!おかげで –

+0

助けになるのはうれしい!ハッピーコーディング:-) –

12

ページのMaster特性は、型System.Web.UI.MasterPageであるとして最初this.Page.Masterをキャストする必要があります。

例えば

((MyMaster)this.Page.Master).MyFunction(); 

あなたはユーザーコントロールの背後にあるコードにプロパティを追加することにより、基本となるマスターページの種類を確認することができます:

を入力し、Userコントロールのマークアップに結果を出力します。それはソースコード内のコメントとして印刷するには、この行を追加します。

<!-- <%= MType %> //--> 
+0

タイプまたは名前空間_Masterを見つけることができないというエラーが表示されます。 –

+0

RunTimeでマスターページのタイプをチェックすることができます。 2番目に答えが更新されます – JDunkerley

+0

タイプはASP.masterpage_masterですが、コンパイル時には使用できません。 –

4

あなたのユーザーコントロール内からマスターページ上の関数を呼び出す場合は、非常にthighlyあなたのコードをcoupplingています。

コントロールは、そのマスターに基づいているページでのみ使用できます。私はこれが通常悪いデザインだと思うし、少なくともデメテルの法律に違反するでしょう。

あなたのコントロールでは、正確に何を達成したいですか?

1

JDunkerleyが正しいです。しかし、私がMVPを使ってそれをどのように切り離すかを説明できるようにして、Heiko Hatzfeldが話しているデザインの問題を回避するように働くことができます。

基本的に、コントロールとマスターページの両方のMVPパターンを実装します。方法については、hereを参照してください。マスターインターフェイス(IMasterView)で呼び出すメソッドを宣言します。次に、2つのコンポーネント間の関係を制御するクラスを作成します。これをPageControllerクラスと呼びます。 global.asaxに次の行を追加することによって、リクエストごとにこのクラスのインスタンスをリクエスト状態にします。CS:あなたは、イベントまたは他の何らかの機構を実現することができる

var controller = HttpContext.Current.Items["Controller"] as PageController; 

:あなたは、コードの次のラインを介してプレゼンター(マスターおよび対照)のそれぞれから、このインスタンスにアクセスすることができ

/* global.asax.cs */ 
protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
    // ... 
    HttpContext.Current.Items["Controller"] = new PageController(); 
    // ... 
} 

コントロールがこの共有オブジェクトを介して分離された方法でマスター上のメソッドを呼び出せるようにします。たとえば:

/* PageController.cs */ 
public event EventHandler SomeEvent; 

protected virtual void OnSomeEvent(EventArgs e) 
{ 
    Debug.Assert(null != e); 

    var handler = this.SomeEvent; 
    if (null != handler) 
     handler(this, e); 
} 

public void FireSomeEvent() 
{ 
    this.OnSomeEvent(EventArgs.Empty); 
} 

/* ControlPresenter.cs */ 
public ControlPresenter(IControlView view) 
    : base() 
{ 
    view.EventFired += (sender, e) => 
    { 
     var controller = HttpContext.Current.Items["Controller"] as PageController; 
     controller.FireSomeEvent(); 
    }; 
} 

/* MasterPresenter.cs */ 
public MasterPresenter (IMasterView view) 
    : base() 
{ 
    var controller = HttpContext.Current.Items["Controller"] as PageController; 
    controller.SomeEvent += (sender, e) => view.MyFunction(); 
} 

は「EventFired」イベントは、あなたのコントロールのインターフェイス(IControlView)で宣言され、コントロールに実装されていることを確認します。マスターに影響を及ぼすために必要なこと(そのメソッドを呼び出す)は、このイベントを発生させ、MVP + PageContollerが残りを処理します。

乾杯

1

私はここに、仕事に上記の回答を得ることができなかった私のために働いていたものです:

あなたはユーザーコントロールからマスターページのプロパティを参照します。その後で

<%@ Register Src="~/Source/MasterPages/Main.master" TagPrefix="MSTR" TagName="MasterPage" %> 

public string BodyClass 
{ 
    set 
    { 
     this.masterBody.Attributes.Add("class", value); 
    } 
} 

が今そうのようなユーザーコントロールASCXファイルでマスターページへの参照を追加します。

まず、あなたのマスターページには、そのようなパブリックプロパティを持っていますコードの後ろに(私の場合はC#)あなたはこのコードを持っています:

Main masterPage = (Main)this.Page.Master; 
masterPage.BodyClass = "container"; 

参照なしあなたのユーザコントロールの上のマスターページには、マスターページクラスを見つけることができません。

関連する問題