2009-06-07 10 views
0

既定のリソースアセンブリのリソースにアクセスする必要があるWPF MarkupExtensionがあります。拡張機能は実行時に正常に機能しますが、拡張機能が起動時アセンブリのデフォルトリソースを見つけることができないため、設計者は失敗します。 ResourceManagerを読み込むには、リソースをロードするアセンブリを知る必要があります。WPFでデザイン時にスタートアップアセンブリを検索

実行時には、アセンブリを初期化で渡すことでこれを簡単に処理できます。これはうまく動作します。

しかし、デザインタイムでは、このスタートアップコードは実行されないので、デザイナーは爆弾を爆発させ、ページの読み込みに失敗します。だから、どのように私は(特定のアプリケーションの種類を参照せずに)一般的に、次のいずれかを取得することができます:

  • アプリケーションの起動アセンブリ (すなわちWPF EXE。)
  • 現在のXAMLドキュメントのマークアップ拡張機能が
  • 上でホストされています

答えて

2

AFAIK、それを行うための簡単でクリーンな方法はありません...私はエントリポイント(つまり実行可能なアセンブリ)を持ち、System.Windowsから派生したクラスを含むアセンブリを探します.applicationの:

public static Assembly GetEntryAssembly() 
    { 
     // Should work at runtime 
     Assembly asm = Assembly.GetEntryAssembly(); 

     // Design time 
     if (asm == null) 
     { 
      asm = (
        from a in AppDomain.CurrentDomain.GetAssemblies() 
        where a.EntryPoint != null 
        && a.GetTypes().Any(t => t.IsSubclassOf(typeof(System.Windows.Application))) 
        select a 
       ).FirstOrDefault(); 
     } 

     return asm; 
    } 

このコードは、特定のニーズに合わせて調整する必要があります(例えば、それはWPFコントロールライブラリのために動作しません)

あなたがXAMLのルート要素を取得することを好む場合、あなたは可能性私はしばらく前に書いたcode of a markup extensionのインスピレーションを見つけます。私/内部フィールドのリフレクションを使用してルート要素を検索します。

+0

ああ、私は前にContextプロパティを見つけていましたが、プライベートリフレクションを使用して却下しました。しかし今では、このシナリオは主にデザイナーのためだと思うので、信頼の問題は問題ではありません。 これは私が正しい方向に向いていると思います。 –

+0

上記のコードは、スタートアップアセンブリを使用しているデザイナで動作します。それでも他のアセンブリにはコントロールが残っていますが、それはかなりマイナーなマークアップ拡張のデフォルトが対応できます。 投稿のFWIW、私的反射コードは便利ですが、残念ながらデザイナーでは失敗します。結局のところ、デザイナーは部分的な信頼関係で動作し、私的な反射の試みは失敗します。コード を完全に中止するだけでなく、例外ブロックはそれをキャプチャしません。 –

+0

奇妙な...私にとってデザイナーはクラッシュしません。とにかく、InputBindingコマンドをViewModelコマンドにバインドするのはちょっとした回避策です。 –

0

Assembly.GetEntryAssembly.FullNameは#1を与えます。あなたの他の問題については、Assembly.GetExecutingAssemblyはしませんか?

+0

実行時には動作しますが、設計者がアプリケーションを引き継ぐので設計時には動作しません。私はデザイン時に最初のアセンブリへの参照を取得する必要があります。 問題は、マークアップ拡張が別のアセンブリにあることです。 今私はそれをメインアセンブリに移動し、そのようにアセンブリを参照しています - それは動作しますが、実際には別のアセンブリに拡張が必要です。 –

+1

GetEntryAssemblyは、設計時にnullを返します... –

関連する問題