質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

3回答

2111閲覧

Windows Formsプロジェクトにおける画像ファイルの管理

ttact

総合スコア170

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

0クリップ

投稿2021/05/07 07:37

編集2021/05/07 07:39

■環境
Windows 10 Pro/Enterprise x64
Visual Studio Professional 2017 ver.15.9系

■質問の概要
Windows Formsの画像リソースの管理方法について不明点が多すぎるので、まとまった資料(特にベストプラクティス的なもの)を探しています。
参考になる資料をご存じでしたら、URL等教えて頂ければ有難く思います。

あるいは、下記「やりたいこと」にしっくりくる手段はVisualStudio上では存在してなくて、自前で.resxファイルを出力するほうが良い等のアドバイスでも頂ければ有難く(でもその場合は.resxファイルの仕様が記述された資料が知りたいです...)。

■やりたいこと
以下を満たす手段を探しています:
0. ボタンのImageプロパティで画像を選択し、デザイナ上で確認したい。
別にボタンに限らないのですが、ようはフォームのデザイナ上でプロパティとしてリストから選択できて、かつデザイナ上で外観を確認できるということです。
0. 画像ファイルは自身でフォルダを管理したい。
ソリューションエクスプローラーから当該プロジェクトを右クリックして「プロパティ」→「リソース」で追加するやり方では、[プロジェクトフォルダ\Resources]フォルダの下にコピーされるが、あくまで元のフォルダにある画像を参照してほしい。
これは多数の画像ファイルを作る際に、デザイナ(≠プログラマ)が管理しやすくするために、フォルダ階層などを細かく分けたいという要件から来ています。
0. ローカライズは不要。

■そのものズバリできると嬉しいことの例
画像ファイル格納フォルダのルートを指定しておくと、ビルド時に.resxファイルの<data>タグを適切に作ってくれて、.resourcesの作成(バイナリ化)までやってくれる。

■今のところ参考にしている情報
Visual Studio でのリソース ファイル
これを読んでも、VisualStudioを使っている場合はResgen.exeは自分で叩く必要はないんだよな...?あれ...?という感じで、何が必要なことなのかよくわからない感じです。読解力がなくて申し訳ありません。

■現下の回避策
0. ソリューションエクスプローラーから当該プロジェクトを右クリックして「プロパティ」→「リソース」で既存のファイルを追加する。
0. .resxファイルをテキストエディタで開き、ファイルのパスを修正する。
0. プロジェクトに追加されたResources下のファイルをソリューションエクスプローラー上で削除する。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/05/07 08:19 編集

リソースに入れずに、専用フォルダから画像直読みとかはダメですかね。 (デザイナ上で確認したいという要望には沿いませんが)
ttact

2021/05/09 23:12

コメントありがとうございます。 デザイナ上での確認は要求の声が大きいので、外せません。
guest

回答3

0

radianさんの回答からあたりをつけて、以下の記事を見つけました。
How to use ResXResourceWriter to create correct Resx file?

ここから、以下のようなツールを作成しました。

C#

1using System.Resources; 2namespace Hoge 3{ 4 classs Program 5 { 6 static void Main() 7 { 8 var dstPath = @"hoge.resx"; 9 using(var writer = new ResXResourceWriter(dstPath)) 10 { 11 foreach(var srcPath in 画像ファイルを列挙) 12 { 13 var name = srcPathから適当に変換(リソース名となる) 14 var res = new ResXFileRef(srcPath, 15 typeof(System.Drawing.Bitmap).AssemblyQualifiedName); 16 var node = new ResXDataNode(name, res); 17 writer.AddResource(node); 18 } 19 writer.Close(); 20 } 21 } 22 } 23}

このツールで出力されたhoge.resxファイルをプロジェクトに追加することで、以下の通り目的が達成されました:

  • ボタンのImageプロパティ等で、プロジェクトリソースファイル(P)のコンボボックスをhoge.resxにすれば、当該画像が選択でき、デザイナ上で表示される。
  • 何も気にしなくてもビルドすることで画像データは.exeに埋め込まれ、.exeのみで画像が表示される。

2021/05/11追記

hoge.resxをプロジェクトに追加してデザイナから画像を選択すると、hoge.Designer.csが作成されます。このDesigner.csの中には画像をSystem.Drawing.Bitmapとしてリソースバイナリストリームから復元するコードが自動生成されます。

ここで、hoge.resxをプロジェクトに追加したに、フォルダ内に画像を追加したとします。

この場合、hoge.resxを更新する必要があることは無論ですが、Designer.csも更新する必要があります。hoge.resxを更新してDesigner.csを更新しない場合、デザイナ上で画像を選択すること自体は問題なく行えるのですが、ビルドすると「'XXXX'に'YYYY'の定義がありません」というコンパイルエラーが発生します。

このコンパイルエラーを防ぐには、以下のようにします。

  • ソリューションエクスプローラー上でhoge.resxのプロパティを開き、「カスタム ツール」の欄に「ResXFileCodeGenerator」と入力する。この作業はhoge.resxを追加した際の1回のみ行えばよい。
  • hoge.resxを(ツールで)更新する度に、ソリューションエクスプローラー上でhoge.resxを右クリックし「カスタム ツールの実行(L)」を行う。これによりDesigner.csが作り直される。

カスタムツールの実行は面倒なので、将来的にはビルド前イベントに組み込みたいですね...


2021/05/11 追記2

Designer.csを自動生成するには、System.Resources.Tools.StronglyTypedResourceBuilderを使えばよいようです。
Programmatically generate Designer.cs for resx file (ResXResourceWriter/ResXResourceReader)

ただしこれで生成したDesigner.csを、.resxと同時にプロジェクトに追加してしまうと、.resxとDesigner.csが別々のものとして認識されてしまいます(.csproj内で<AutoGen>等が付与されない等等)。なので、初回生成のときだけは.resxファイルのみを追加し、上記の通りカスタムツールを設定して自動生成し、StronglyTypedResourceBuilderは更新時のみ使うようにしたほうが(今わかっている範疇では)楽かなと思います。

投稿2021/05/10 05:44

編集2021/05/11 05:02
ttact

総合スコア170

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

ワイルドカードで埋め込み対象指定できるみたいなので、それで画像用フォルダ指定してまとめて埋め込めるかもしれません。(試してません)
C#のアプリケーションにリソースを埋め込み、利用する

あとは、一応プログラム的にresxを作成する方法はあるみたいなので、自力で画像用フォルダからいい感じのresxを出力するとか?
.resxファイル(XMLリソースファイル)を作成する、読み込む

投稿2021/05/10 01:18

編集2021/05/10 02:32
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ttact

2021/05/10 05:34

ご回答ありがとうございます。 (1) 「C#のアプリケーションにリソースを埋め込み、利用する」については、ワイルドカードで指定することで画像ファイルをプロジェクトに追加することはできたものの、それをボタン等のImageで利用しようとしても選択肢には出てきませんでした。.resxに追加するほうは別途必要なようで、(fanaさんのコメントに暗黙的に書きましたが).resxに記載があればむしろプロジェクトへの追加は不要なようです。 (2) ResXResourceWriterクラスを使って.resxファイルを作成する方法は、結果としては期待通りの効果が得られました。詳細は回答として記述させて頂きます。 大変ありがとうございました!
guest

0

画像ファイルは自身でフォルダを管理したい。

ソリューションエクスプローラーから当該プロジェクトを右クリックして「プロパティ」→「リソース」で追加するやり方では、[プロジェクトフォルダ\Resources]フォルダの下にコピーされるが、あくまで元のフォルダにある画像を参照してほしい。

プロパティで「コンパイル時にリンクされました」とかいうのを選べばコピーされずにその場から参照されます.(下図赤枠)

イメージ説明

とりあえず,これだけで

やりたいこと

を最低限満たすのではないでしょうか?

投稿2021/05/07 08:22

fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ttact

2021/05/09 23:21

ご回答ありがとうございます。 上記の状態にする際、元のフォルダからコピーされないようにするには、VisualStudio上でどのように操作したらよいのでしょうか? Resources.resxをご提示頂いた画像のように開いた状態にしてそこにドラッグ&ドロップをした場合、あるいは「リソースの追加(R)」→「既存のファイルの追加(R)」で追加した場合は、どちらもファイルがResources下にコピーされてそれを参照してしまい、結果私が質問で書いた通り.resxファイルをテキストエディタで手編集してリンク先画像のパスを書き換える必要がありました。
fana

2021/05/10 01:46 編集

図内赤枠のプロパティ"Persistence"の選択がデフォルトで「.resxに埋め込まれました」になっているとしたら,リソースを追加した瞬間に(?) > ファイルがResources下にコピーされてそれを参照してしまい という状態にひとまずなってしまうでしょうが, その後で,このプロパティを変更してやることで(図内で一個上の欄の)"Filename"に示された場所から参照するように設定を変更することができます. Resourcesフォルダにコピーされたファイルは参照されなくなるハズです(→要らないなら手動で消すしかないのかな)
ttact

2021/05/10 04:50

コメントありがとうございます。 その後、以下の手順でファイルがコピーされずにリンクのみ作成でき、.resxを手修正する必要がないことがわかりました。 (1) ソリューションエクスプローラーで対象のプロジェクトの適当なフォルダを右クリック→「追加」→「既存の項目(G)...」 (2) 画像を選択し、「追加(A)」ボタンの右側にある小さな「▼」を押下して「リンクとして追加(A)」 (3) 追加されたリンクを、ソシューションエクスプローラーから.resxの編集部分にドラッグ&ドロップ (4) リンクを削除
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問