フリッカーの標準的な治療法はダブルバッファリングです。しかし、それはこの種のちらつきを解決することはできません。それは、互いに重なり合う複数のウィンドウを有することによって引き起こされる異なる種類である。各ラベルは独自のウィンドウです。フォームが自身をペイントする必要があるとき、フォームはバックグラウンドを描画して、子ウィンドウのための穴を残します。それぞれの子ウィンドウはそれから順番に描画を行います。そして、その子ウインドウは自分自身を引き出します。 Etcetera。
これは、1つのコントロールが描画するのに時間がかかり、間違いなく画像ボックスが表示されている場合に顕著になります。特に、サイズ変更が必要な大きな画像を表示する場合。子ウィンドウの穴は、ピクチャボックスが描画されている間は塗装されていません。フォームのTransparencyKeyプロパティまたはOpacityプロパティを使用すると、白い背景、黒色になります。これはあなたの画像ボックスの画像とは非常に対照的であり、その効果はユーザによってちらつきとして知覚される。
すぐに解決できるのは、コントロールを使用しないために窓口に支払いをしないことです。ラベルは非常に便利ですが、単に文字列を表示するためにウィンドウを焼くのはシステムリソースの大量な浪費です。ピクチャボックスのPaintイベントを実装し、TextRenderer.DrawText()で文字列を描画するだけで済みます。 PictureBoxはデフォルトでダブルバッファリングを有効にしているので、画像とテキストは完全にスムーズに描画され、ちらつきは発生しません。明らかな欠点は、ポイントアンドクリックの利便性を失うことです。コードを書く必要があります。
他にも修正があります。それらの1つは、ピクチャボックスがチャイルドウィンドウ用の穴を残さないようにすることです。画像全体が描画され、その上にラベルが表示されます。それはまだちらつきですが、それほど顕著ではありません。プロジェクトに新しいクラスを追加し、このコードを貼り付けます。
using System;
using System.Windows.Forms;
internal class MyPictureBox : PictureBox {
protected override CreateParams CreateParams {
get {
var parms = base.CreateParams;
parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
return parms;
}
}
}
コンパイルし、フォーム上にツールボックスの上から新しいピクチャボックスコントロールをドロップします。
さらに別の回避策として、フォームとそのすべての子をダブルバッファリングすることがあります。これはペイント全体をスピードアップするわけではなく、すべてのウィンドウがメモリバッファにレンダリングされ、結果が画面にブリットされます。遅れがあるのが分かりますが、ウィンドウが突然画面に表示されます。これを合成といいます。 Winformsはこれを直接サポートしていませんが、副作用がある可能性がありますが、有効にするのは簡単です。このコードをフォームクラスに貼り付けます。
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
XP以降でサポートされています。ペインティングアーチファクトに注意してください。
有望です! – Arcturus
値が変更されないラベルに対しては正常に動作しますが、一部のラベルには定期的に更新される値があります。ペイントイベント内でTextRendererを使用すると、値はどのように更新されますか? – Arcturus
@Arcturus call pictureBox.Invalidate() – LarsTech