1

私は Windows フォーム アプリケーションを開発しており、一連の画像 (アイコンと考えてください) を使用します。テーマに応じて、さまざまな画像セットを選択する必要があります (後で を使用して描画しますBitmap)。

画像を別のファイル (アーカイブ ファイル? dll?) に保存し、実行時にメイン アプリケーションから読み込むことを考えていました。これを行う最も効果的な方法は何ですか?

読んでくれてありがとう。

4

3 に答える 3

3

いくつかのシナリオを考慮して、これに答えます。

  1. この画像は頻繁に変更されますか? 次に、ディレクトリベースのアプローチに進み、ディレクトリに保存してロードします。ロードするこれらのファイルの名前を持つ xml を持つことができるかもしれません。ファイル(画像)の名前を変更するので、xmlを変更するだけです。

  2. これらのファイルは変更されませんか? 次に、それらをリソースとして埋め込むだけで、exe / dllに埋め込まれ、画像が破損することはありません。

通常、埋め込みを行っていない人を見てきました。

于 2011-09-03T17:37:25.603 に答える
0

resxファイル(リソースファイル)の使用を考えましたか?このようにして、任意の画像(アイコン)または好きなものを埋め込んで、テーマに基づいて必要なリソースファイルのみをロードすることを決定できます(リソースファイルにはテーマ名に基づいて名前を付けることができます)。ローカライズ時に発生したのと同じ問題のようですね。しかし、それが最善の方法(パフォーマンス、メモリなど)であるかどうかを知るには、わかりません。

于 2011-09-10T06:24:47.197 に答える
0

探していた答えが得られたかどうかはわかりません。リソース dll を作成する手順は次のとおりです。

  1. Visual Studio、クラス ライブラリで新しいプロジェクトを作成する
  2. リソース (写真) をプロジェクトに追加します (既存のアイテムを追加)
  3. リソースごとに、プロパティ ウィンドウで [ビルド アクション] を [埋め込みリソース] に設定します。
  4. ライブラリをコンパイルし、dll を生成します
  5. winforms アプリケーションで、実行時にこのアセンブリをロードできるようになりました (コード #1)
  6. 必要なリソース ストリームを読み込み、Bitmap オブジェクトに保存します (コード #2)

コード#1

Assembly ambly = Assembly.LoadFile(pathToDll);

コード #2

BitMap bitMap;
// where "ns" is the default namespace of the resource project    
using (Stream resourceStream = ambly.GetManifestResourceSream("ns.image.jpg"))
{
      bitMap = BitMap.FromStream(resourceStream);
}

これらは、リソースを埋め込み、実行時にロードするために使用される基本的な手法です。

ここで、さまざまなテーマを用意し、各テーマのリソースをさまざまなライブラリに保存することを考えているので、メイン アプリケーションで定義された、ある種のリソース マネージャーを指定するインターフェイスが必要です。

interface IThemeResourceProvider
{
     Stream LoadBigLogo();
     Stream LoadSmallLogo();
} 

次に、そのインターフェイスをリソース ライブラリに実装します

public class ThemeResourceProvider : IThemeResourceProvider
{
    public Stream LoadBigLogo()
    {
         Assembly ambly = Assembly.GetExecutingAssembly();
         return ambly.GetManifestResourceStream("namespace.image.jpg");
    }

    (...)
}

最後に、リソースをメイン アプリケーションに直接ロードする代わりに、リソース ライブラリにある IThemeResourceProvider をインスタンス化します。

 Assembly assembly = Assembly.LoadFile(pathToDll);

 var results = from type in assembly.GetTypes()
               where typeof(IThemeResourceProvider).IsAssignableFrom(type)
               select type;

これIEnumerable<Type>で、そのリストに があります。通常は 1 つしかありませんが、このアプローチを使用すると、複数のリソース セットをホストし、同じリソース dll に複数の IThemeResourceProvider を実装することもできます。たとえば、プロパティとして、または[Attribute]さまざまな実装でカスタム装飾を使用して、各 IThemeResourceProvider を名前で識別することができます。残りはあなたに任せます。

ただし、リストで IThemeResourceProviders をインスタンス化する方法は次のとおりです。

foreach (var providerType in results)
{
     var constructorInfo = providerType.GetConstructor(Type.EmptyTypes);
     IThemeResourceProvider provider = constructorInfo.Invoke(null);
}

最後に、これらのプロバイダーのいずれかを使用してビットマップを取得します。

BitMap bitMap;
using (Stream resourceStream = provider.LoadBigLogo())
{
      bitMap = BitMap.FromStream(resourceStream);
}
于 2011-09-10T08:57:06.523 に答える