2017-08-01 14 views
0

私はデフォルトでは無効になっていて表示されていない画像ボックスでWinFormsアプリケーションを作成しています。私は、フォームのラジオボタンをクリックすると、私は、画像ボックスを表示すると、その直後に、私は何かが彼らの上に描画することにしたい。C#で何が起こるかPictureBox.VisibleがTrueに設定されている場合

// the radio button CheckedChanged event handler: 
table1PictureBox.Enabled = true; 
table1PictureBox.Visible = true; 
DrawCorrectAnswers(); // draw something over the picture box 

問題は絵が行われる前に描画が終了するということです見えるので、図は最終的に画像で覆われます。

私はhereを読んで、Visibilityをtrueに設定した後、実際のイメージの読み込みがフォームのメッセージキューに入れられていることを確認しました。その答えは、タイマーを設定して、そのティックを非同期的に待ってから描画を行うことで、画像の読み込みに時間がかかる可能性があるということを示唆しています。私はタイマーを設定して解決策が気に入らず、代わりに写真そのものが読み込まれるのを待っています。

これを行う方法はありますか?この場合、Visibleをtrueに設定することはどのくらい正確に機能しますか?


また、私はこのように見えた別の解決策を考え出すことを試みた:

// the radio button CheckedChanged event handler: 
table1PictureBox.Enabled = true; 
table1PictureBox.Visible = true; 
this.BeginInvoke(new Action(() => { DrawCorrectAnswers(); })); // 'this' is the form 

私の考えでは、これがロードするためのメッセージの後に描画するためのメッセージ、そうでも操作をキューというものでした必要な順序で実行されます。しかし、これはうまくいきませんでした。

この場合、フォームのスレッドにある場合、BeginInvokeの特別な動作があるかもしれませんか?私は通常のInvokeを試してみましたが、驚いたことに、デッドロックは発生しませんでした。何故ですか?


[EDIT】ここで、問題を示して最小限の例です:

public Form1() 
    { 
     InitializeComponent(); 

     pictureBox1.Visible = false; 
     pictureBox1.Enabled = false; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     pictureBox1.Enabled = true; 
     pictureBox1.Visible = true; 

     Graphics graphics = pictureBox1.CreateGraphics(); 
     graphics.DrawLine(Pens.Black, 0, 0, 50, 50); 
    } 
+0

DrawCorrectAnswers関数のコードを追加して、あなたの問題はイメージの読み込みではなく、画像の再描画と思われます。 – Gusman

+0

@Gusman例を追加しました。 – honzukka

+0

そして私は答えを追加しました:D – Gusman

答えて

2

コントロールはあなたのすべてを再描画ますいつでもここでの問題は、あなたが、ではない画像で、ピクチャボックスに描画されていますあなたがそれを描くとそれが消去され、それを描く必要があります。

private void button1_Click(object sender, EventArgs e) 
{ 

    Bitmap bmp = Bitmap.FromFile(pathToTheFile); 

    using(var graphics = Graphics.FromImage(bmp)) 
     graphics.DrawLine(Pens.Black, 0, 0, 50, 50); 

    var oldImg = pictureBox1.Image; 
    pictureBox1.Image = bmp; 

    if(oldImg != null) 
     oldImg.Dispose(); 

    pictureBox1.Enabled = true; 
    pictureBox1.Visible = true; 

} 

注いくつかのもの:任意のグラフィックスでは、作成したオブジェクトを、より良い常に処分

よりよい解決策は、手動で画像を読み込む画像の上にテキストを描画し、その後のPictureBoxにそれを設定することですそれをブロックusingで囲みます。また、不要なときには未使用のイメージを破棄してください。そのため、古いイメージを取得して、それが存在する場合はそのイメージを破棄します。

最後に、イメージを物理ファイルとして含めたくない場合は、イメージをリソースとして組み込むことができます。その方法の例はたくさんあります。

EDIT:

あなたは真の可視設定ボンネットの下に何が起こる

は、ピクチャ領域が(その後、表示されるコントロールは、その長方形と交差する形でテストする次の描画サイクルで、フォーム上で無効化されていることですまたは他の無効化された領域)を作成し、それらを描画します。

また、Invokeについて、なぜデッドロックが発生するのでしょうか?呼び出しを呼び出すときにロックを使用していない場合はスレッドをチェックします。スレッドがUIであれば関数を実行し、そうでない場合はUIスレッドに呼び出しをポストし、呼び出し元はブロックされます。 UIは関数呼び出しを処理しました。

+0

ありがとう、これは私のアプローチよりもはるかに理にかなっています! – honzukka

+0

@honzukka答えが正しい場合はそれを受け入れてください。 – Gusman

+0

私はまだ私が持っていた追加の質問への回答を得たいと思います。私はあなたのアプローチが私の必要としている方法で動作することを理解していますが、私はまだ私の試みで間違っていたものを理解していません。私にはまだ不明ないくつかの概念があります。私は質問に間違って言いましたか? (ご覧のとおり、これは私の最初の投稿です...:D) – honzukka

関連する問題