2009-03-03 15 views
7

私は現在、いくつかのコンポーネントから構成されているアプリケーションを構築しています。これらのコンポーネントのそれぞれは、プラグインシステムが動作するように(C++を使用して) 。非WPFコードからのWPF XAMLリソースへのアクセス

私が抱えている問題は、各コンポーネントにアイコンを含める必要があり、正真正銘の目的のために、System.Windows.Media.Brushと定義したので、DesignからエクスポートされたDrawingBrushを使用することができます。私はそれを読むための方法を見つけることができませんでした

private Brush CachedIcon = null; 

public override Brush Icon 
{ 
    get 
    { 
     if (CachedIcon == null) 
     { 
      CachedIcon = (Brush)(new BlahControl().TryFindResource("Icon")); 
     } 
     return CachedIcon; 
    } 
} 

:今、私は現在、ユーザーコントロールをインスタンス化し、リソースのためにそれを求めての恐ろしい回避策を持っている非WPFのC#からXAMLのその部分にアクセスする必要がありますリソース(.xamlファイルで、カスタムコントロールのResourceDictionaryで参照されています)を「通常の」C#クラスから削除します。 WPFに属するものはどれもTryFindResourceという素敵な方法ですが、それ以外の方法はありますか? XAMLファイルのアイコンが埋め込まれていないようにすることは望ましくありません。

答えて

2

アイコンリソースは、「リソース」に設定し、ビルドオプションを持っていることを確認し、その後、あなたの.NET 2.0のコードで次に、あなたがそれXAML静的リソース

<UserControl.Resources> 
    <BitmapImage x:Key="icon1" UriSource="Resources/Icon1.ico" /> 
</UserControl.Resources> 

作るためのリソースを参照します

using System.IO; 
using System.Reflection; 
using System.Collections; 
using System.Resources; 

... 

var icons = new Dictionary<String, Bitmap>(); 
var externalBaml = Assembly.LoadFile(Path.Combine(Environment.CurrentDirectory, "MyXaml.dll")); 
Stream resourceStream = externalBaml.GetManifestResourceStream(externalBaml.GetName().Name + ".g.resources"); 
using (ResourceReader resourceReader = new ResourceReader(resourceStream)) { 
    foreach (DictionaryEntry resourceEntry in resourceReader) { 
     if (resourceEntry.Key.ToString().ToUpper().EndsWith(".ICO")) { 
      icons.Add(resourceEntry.Key.ToString(), Image.FromStream(resourceEntry.Value as Stream) as Bitmap); 
     } 
    } 
} 
+0

仕事をしているようだが、騒々しいように見える。自動的に生成されたリソースの内部名に依存することは、私にはあまりお勧めできません。 – Joey

+0

Ehh?リソースには文字列名がありますが、それについて何もできません!何を探していますか? – TFD

+0

私は、 ".g.resources"がどれほど信頼できるものであることが証明されているのか不思議に思っていました。私はレイモンド・チェンのブログを十分に読んだことがあります。それは、実際には実装の成果物であり、文書化された動作ではないため、何も使用したくないということです。 – Joey

0

アセンブリからストリームとしてリソースを読み取ることができます。ここ

例コード: http://www.wpftutorial.net/ReadWPFResourcesFromWinForms.html

+0

うーん、それは今の仕事を得ることができませんでした、後でaganiをしようとします。しかし、これは問題の賢明な解決策として私を襲っているわけではありません。しかし、BuildアクションをPageではなくResourceに設定すると、明らかにXAMLファイルがXAMLとして埋め込まれます。そのような良い選択肢かもしれません。私が試してみます。 – Joey

0

がapp.xamlまたはマスターリソースディクショナリXAMLファイルのいずれかで、アプリケーションレベルではなく、コントロールにアイコンを定義します。その後、同じTryFindResourceメソッドを使用できますが、コントロールのインスタンスは作成されません。あなたのXAMLコードで

+0

プロジェクトはWPFアプリケーションではなく、ユーザーコントロールのみであるため、App.xamlはありません。 ResourceDictだけを持っている場合、どこでTryFindResourceを呼び出しますか?アイコンは既に1つに存在します。 – Joey

1

私の提案:「{} xamlName .g.resource」辞書にXAMLのDLLからすべてのアイコンをロードするストリーム

サンプルコードでリソースを見つけるだろう次のとおりです。

  • アイコンがどこにあるかについてのあなたのコントロールに関するメタデータを提供します。独自のカスタム属性でこれを行うことができます(下記の例1を参照)。このメタデータを使用すると、コントロールのインスタンスを作成せずにアイコンをロードできます。

  • MEFを使用しているため、エクスポートでメタデータを使用して上記と同じようにすることができます。詳細here。下記の例2を参照してください。

  • アイコンをBrushではなくImageSourceとして扱います。 WPFのImageコントロールを使用してImageSourceを表示したり、ImageBrushでペイントすることができます。

  • TFDが提供する手法を使用して、メタデータで指定された名前のリソースを読み取ります。残念なことに、WPFはBamlReaderのようなものを提供するようには見えないので、WPF以外のコンテキストからWPFリソースを読み込むのがはるかに洗練されます。

例1:

[Icon("MyIconResourceName")] 
public class BlahControl : Control 
{ 
    ... 
} 

例2:

[Export(typeof(IApplicationComponent))] 
[ExportMetadata("IconResource", "MyIconResourceName")] 
public class BlahControl : Control 
{ 
    ... 
} 
関連する問題