質問者
VisualStyle有効時にTabControlのタブに画像が表示できないことがある

質問
-
開発時のデザイナ画面では問題なくタグにアイコンが表示されておりましたが、ビルド後、exeを実行すると、アイコンが表示されません。
詳しく説明しますと、もともとVS.NET 2003で開発したアプリケーションで、VS.NET 2005に移行しました。
また、
Application.EnableVisualStyles();
としてVisualStyleを有効にしました。
ImageListにアイコン(16x16)をセットし、TabControlにImageListを割り当て、tabPageごとにImageIndexを指定しました。
不思議なことに、上のVisualStyleを有効にするコードをコメントアウトすると問題なくアイコンが表示されました。また、何十回もリビルドを実行すると、まれに表示できたりします。
それではと思い、テストを目的に、新しくプロジェクトを作成し、フォームに単にTabControlを設置して再現してみました。すると、VisualStyle有効のままでうまくいきます。
まったく原因が不明です。VisualStyleを有効にした状態でアイコンが表示できるようにならないでしょうか。
※気になること
TabControlのタブもそうですが、ListViewのStateImageListにImageListをセットしてチェックボックスの有効・無効を独自に用意したアイコンで表示させていますが、このListViewのアイコンもうまく表示できません。上とまったく同じようにVisualStyleが有効な場合は表示できなくなります。
Button内にもアイコンを設置していますが、これは問題なく表示できています。どうやらImageListに設置した場合に生じる現象ではないかと推測しています。
すべての返信
-
早速の回答ありがとうございます。
僕も以前にApplication.DoEvents()をすることで解決することがあるということを見たことがあるので、実際にやってはみましたが、それでもタブにアイコンは表示されませんでした。再度おこなってみましたがやはり表示できません。
実際のエントリポイントは次のようにしています。
また、IDEが作成するエントリポイントではなく、独自にRunClassなどとクラスを作ってその中でMain()を定義しています。[STAThread]
static void Main()
{
//visualスタイルを有効にする。
Application.EnableVisualStyles();//起動時に行うチェックなど。(省略)
System.Windows.Forms.Application.Run(new MainForm());
}※VS.NET 2005へ移行した際は、VisualStylesが有効になってなかったのですが、有効にしたかったので後で上のコードにあるように、Application.EnableVisualStyles()を読み出して有効にしてみました。
-
また追記させてください。
この現象ですが、最初の質問の際に
何十回もリビルドを実行すると、まれに表示できたりします。
と記載しましたが、今何度かテストをやってみると、リビルドせずとも、まれに表示できることを確認しました。つまり、起動のたびにアイコンが表示したり、しなかったりという現象が起きます。頻度としては20回ほどテストを行ううちの1回は正常にアイコンが表示されます。ほとんどアイコンが表示されません。また、一度アイコンが表示できれば、何度、その子フォーム(ChildForm)をCloseして再度new ChildForm()しても正常にアイコンは表示できました。
ためしに、以下の方法を試しましたがうまくいきませんでした。
・ImageListを削除して作り直す。
・新たにテスト用TabControlを配置してテストする。
・ImageListにセットする画像をpngファイルからicoファイルに変えてみる。
・TabControlのImageListとTabPageのImageIndexの指定をIDEからではなく、コード上で行ってみる。
・new ChildForm()を実行する前にApplication.EnableVisualStyles()を実行する。(間違った方法だとは知りつつもやってみた)
・エントリポイントでApplication.EnableVisualStyles()の後にApplication.DoEvents()を実行する。次のようにすると確実にアイコンは表示され正常です。
・エントリポイントのApplication.EnableVisualStyles()をコメントアウトにしてVisualStyleを無効にすると正常。
とても不思議な現象です...。
-
その後、いろいろ試してみて、原因まではわかりませんでしたが、起動時に行っている以下の操作をコメントアウトすることで現象がでなくなりました。
スプラッシュ画面を表示させているのですが、その表示の処理で、whileで無限ループさせ、その間、経過時間を算出して5秒以上たてばスプラッシュ画面を終了させるということをしていました。while内にApplication.DoEvents()を記載して画面の描画を強制させていました。この部分が影響していたのかな?とも考えてますが、原因は不明です。
とりあえず、スプラッシュ画面を別スレッド化し、Application.DoEvents()を利用しないことで回避できました。今のところ現象が出なくなりましたので解決したのではないかと思います。
まさか起動時のwhile内のApplication.DoEvents()が影響しているとは考えもしませんでした。whileで無限ループっていう処理はスマートではないので後で修正するつもりだったので、その修正の際に現象が改善したことに気づきました。
そのまま様子を見てみたいと思います。ありがとうございました。