DOBON.NET DOBON.NETプログラミング掲示板過去ログ

フォームのサイズ変更後に図形が消えないようにするには?

環境/言語:[OS : Windows XP Home Edition / 言語 : Visual Basic .NET]
分類:[.NET]

【解決したい問題】

お世話になっています。
BBです。

GDI+で図形を作成した場合、
フォームのサイズを変更したり、
最小化したり、最大化すると、
作成した図形が表示されなくなるようですが・・・

サイズを変更しても、
図形が消えないようにすることはできないのでしょうか?

どうかよろしくお願いいたします。
お世話になります。

■No13140に返信(BBさんの記事)
> 【解決したい問題】
>
> お世話になっています。
> BBです。
>
> GDI+で図形を作成した場合、
> フォームのサイズを変更したり、
> 最小化したり、最大化すると、
> 作成した図形が表示されなくなるようですが・・・
>
> サイズを変更しても、
> 図形が消えないようにすることはできないのでしょうか?
>
> どうかよろしくお願いいたします。

昨日の宇宙仮面さんのページに書いてありますね。
http://ukamen.hp.infoseek.co.jp/Programming1/GDI/index.htm#SEC17
こちらのサイトの Tips にもあるので、参考までに。

画像ファイルを表示する
http://dobon.net/vb/dotnet/graphics/drawimage.html
なおこさん、深山さん、ありがとうございました。
BBです。

教えていただいたページを参照し、内容や動作を確認したのですが・・・

応用が利かなくて申し訳ないのですが、まだ、解決していません。


私のやりたい事を、もう少し詳しく、かつ簡単に説明しますと、
TextBox1に数値を入力して、Button1をクリックすると、
その数値の厚さの長方形をPictureBox1に作成したいのです。
これを次々と実行することによって、全体としては帯状の長方形となります。
これを実行するために、以下のように記述しました。
(簡略化のために、HatchStyleは2パターンとしていますが、実際は、数十種類の
パターンを用意しており、そのパターンも任意指定できるようにしています。)


 Dim i As Integer
 Dim dh As Integer

 Private Sub Button1_Click(ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button1.Click
   Dim j As Integer
   j = i Mod 2
   Dim gr As Graphics = Me.PictureBox1.CreateGraphics
   Dim br1 As New HatchBrush(HatchStyle.LargeGrid, _
       Color.LightSalmon.MistyRose)
   Dim br2 As New HatchBrush(HatchStyle.Percent50, _
       Color.White, Color.Blue)
   If j = 0 Then
     gr.FillRectangle(br1, New Rectangle(0, dh, 200, _
        CInt(TextBox1.Text)))
     br1.Dispose()
   Else
     gr.FillRectangle(br2, New Rectangle(0, dh, 200, _
        CInt(TextBox1.Text)))
     br2.Dispose()
   End If
     dh += CInt(TextBox1.Text)
     i += 1
 End Sub

その結果、次々と厚さの異なる長方形が、連続して帯状に作成されるのですが、
サイズ変更すると、消えてしまいます。
このような場合に画像が消えないようにするための良い方法がありましたら、
教えていただけないでしょうか?

もし、以前教えていただいたリンク先のページの情報で、
上記の問題が解決できるのであれば、
私の知識不足で質問が重複してしまったことをお詫びいたします。

以上、よろしくお願いいたします。


■No13143に返信(深山 さんの記事)
>  こちらのサイトの Tips にもあるので、参考までに。
> 
> 画像ファイルを表示する
> http://dobon.net/vb/dotnet/graphics/drawimage.html
>その結果、次々と厚さの異なる長方形が、連続して帯状に作成されるのですが、
>サイズ変更すると、消えてしまいます。

なぜ消えると思いますか?
それはPaintイベントで描画処理をしていないからです。
以下のTipsでそのことが書かれています。

> ■No13143に返信(深山 さんの記事)
>> こちらのサイトの Tips にもあるので、参考までに。
>>
>>画像ファイルを表示する
>>http://dobon.net/vb/dotnet/graphics/drawimage.html

この説明で、読んで試してみて、どの辺りが不明だったのでしょう?
BBです。

皆さん、ありがとうございました。
また、すみませんでした。

どうやら、私の知識がやはり不足していたようです。

http://dobon.net/vb/dotnet/graphics/drawimage.html

の内容は、印刷までして、動作も確認していたので、
理解していたつもりです。

私はButtonをクリックすることによって、描画させたかったので、

Buttonクリック = Button1_Clickイベントで描画処理するしかない

というように思い込んでいました。
しかし、絶対にPaintイベントでなければいけないということは、
おそらく、Buttonクリックの動作から、
Paintイベントを実行させる方法があるということなんですね?

お騒がせしました。

もう少し、勉強してみます。


■No13223に返信(よねKENさんの記事)
> なぜ消えると思いますか?
> それはPaintイベントで描画処理をしていないからです。
> 以下のTipsでそのことが書かれています。
>
>>■No13143に返信(深山 さんの記事)
> >> こちらのサイトの Tips にもあるので、参考までに。
> >>
> >>画像ファイルを表示する
> >>http://dobon.net/vb/dotnet/graphics/drawimage.html
>
> この説明で、読んで試してみて、どの辺りが不明だったのでしょう?
>
> おそらく、Buttonクリックの動作から、
> Paintイベントを実行させる方法があるということなんですね?

この文面からだとあえて違いますと言っておきます。

スクリーンにボタンやテキストボックスなど表示されてると思います。
で、なぜ表示されているかということですが、
まずWindowsにはGUI(グラフィックによる表現)の単位としてウィンドウクラスというベースの部品があります。
#例えばコンボボックスはテキストボックスとリストボックスの組み合わせでできています。
そこでいうウィンドウの単位にウィンドウプロシージャというOSからのメッセージを受け付け処理するプロシージャがあり
その中でPaintを受け取ると自分を描画します。(Paintだけではないです)
例えば、ある画面をドラッグして後ろにいた画面が表に出てきたときに
再描画が必要な部分を含むウィンドウプロシージャに再描画しろというメッセージが送られ
そのウィンドウプロシージャにより描画されるのです。

ここでウィンドウプロシージャが描画するものはウィンドウプロシージャに定義されているものだけです。
テキストボックスであれば、背景を白で塗り、周りにボーダーを書き、影を付け、、、という決まりきったもの、
つまり、ユーザーが勝手に描画したものはその時点で上書きされて結果的に消えるわけです。

最初に違いますと言ったのは、
描画する必要性(位置の変更や他のウィンドウとの重なりなど)があるから描画する
というのが処理のきっかけ(トリガー)ですということです。
強制的に再描画させるというのはひとつの手段ではありますが
それですべてまかなえないということが伝われば幸いです。
> しかし、絶対にPaintイベントでなければいけないということは、
> おそらく、Buttonクリックの動作から、
> Paintイベントを実行させる方法があるということなんですね?

ControlクラスのInvalidateメソッドも調べてみてください。
文面からすると後はこれで解決するかもしれません。
ご無沙汰しています。
BBです。

アドバイスをして頂いた皆さん、
本当にありがとうございました。

その後、人には言えないような、
妙な方法を試したりもしながら、
試行錯誤の結果、何とか解決することができました。

どのように行ったかといいますと・・・

Buttonクリックから、Invalidateメソッドを実行して、再描画を促す。
ただし、四角形の厚さなどの情報は、ユーザー入力値より得ているため、
以前に入力した入力値は存在しないため、それらを配列に保存することによって、
配列に収納された情報をもとにPaintイベントで四角形を描画する。

というような感じで解決しました。

解決したい問題から派生して、
皆さんからのアドバイスをベースに、
その他にもいろいろなことが勉強になりました。

本当にありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板