7

現在、私は簡単な作業だと思ったことをやろうとしています。

PanelWindowsフォームのコントロールの全領域に画像を描画します。BackgroundImage(プロパティを使用できるので、今のところ無視してください)

描画する画像は次のようになります。

ここに画像の説明を入力してください

つまり、周囲に1ピクセルの青いフレームがある黄色のボックスです。

描画するために、コントロールのPaintイベントを使用しています。Panel

private void panel1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawImage(Resources.MyImage, panel1.ClientRectangle);
}

これは、最初にフォームを表示するときに問題ないように見えます。

ここに画像の説明を入力してください

フォーム(およびドッキングされたパネルも)のサイズを変更すると、小さくするとエッジがカットされます...

ここに画像の説明を入力してください

...または大きくすると、アーティファクトが描画されます。

ここに画像の説明を入力してください

かなり単純でわかりやすいことが起こっていると確信していますが、その理由は本当に理解できません。

を無視してClipRectangle常にすべてを描いているので、画像は常に拡大縮小されると思いました。

私の質問は次のとおりです。

  • アーティファクトの理由は何ですか?(私はこれを理解するのが大好きです!)
  • 遺物を取り除くために私は何をしなければなりませんか?Invalidate(各サイズ変更を呼び出す以外に)

更新、解決策:

ライアンの答えのおかげで、私は許容できる解決策を見つけることができました。基本的に、私はからクラスを派生さPanelせ、オーバーライドを実行し、基本メソッドを呼び出しOnPaintBackgroundませんでした。最後に、派生パネルのコンストラクターに次のコードを追加しました。

base.DoubleBuffered = true;

SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

UpdateStyles();
4

1 に答える 1

5

アーティファクトの理由は、フォームのサイズが変更されたときに表面全体が再描画されないことです。必要な部品だけです。Invalidate一般的に最善の解決策は、サイズ変更のたびに呼び出して、やりたくないことです。ただし、これが実際の状況である場合は、PictureBox代わりに a を使用してください。そうでない場合は、OnPaint代わりにフォームでオーバーライドし、this.SetStyle(ControlStyles.ResizeRedraw, true)これを自動的に行うために使用することを検討してください。

于 2012-03-17T15:54:52.953 に答える