背景のあるWindowsフォームアプリケーションがあります。その中に、背景が透明なflowlayoutpanelがあります。スクロールすると、次のようになります。
ちらつきも見られます。私はすべてのダブルバッファービジネスを試しましたが、うまくいきません。
助言がありますか?
背景のあるWindowsフォームアプリケーションがあります。その中に、背景が透明なflowlayoutpanelがあります。スクロールすると、次のようになります。
ちらつきも見られます。私はすべてのダブルバッファービジネスを試しましたが、うまくいきません。
助言がありますか?
これは私のために働いたものです。
public class CustomFlowLayoutPanel : FlowLayoutPanel
{
public CustomFlowLayoutPanel()
: base()
{
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
protected override void OnScroll(ScrollEventArgs se)
{
this.Invalidate();
base.OnScroll(se);
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // WS_CLIPCHILDREN
return cp;
}
}
}
ええ、それはうまくいきません。これをいくらか改善するクラスは次のとおりです。
using System;
using System.Windows.Forms;
class MyFlowLayoutPanel : FlowLayoutPanel {
public MyFlowLayoutPanel() {
this.DoubleBuffered = true;
}
protected override void OnScroll(ScrollEventArgs se) {
this.Invalidate();
base.OnScroll(se);
}
}
コンパイルして、ツールボックスの上部からフォームにドロップします。ただし、根本的な問題である「ドラッグ中にウィンドウコンテンツを表示する」オプションは修正できません。これはシステムオプションであり、以降のバージョンのWindowsではオンになります。オンの場合、Windows自体がパネルのコンテンツをスクロールし、スクロールによって表示された部分を描画するようにアプリに要求します。OnScrollメソッドはそれをオーバーライドし、ウィンドウ全体が再描画されて背景画像が所定の位置に保持されるようにします。最終結果はきれいではありません。スクロールしながら上下にジャンプする「pogo」を実行している画像が表示されます。
これに対する唯一の修正は、システムオプションをオフにすることです。これは実用的な修正ではありません。ユーザーはこのオプションを好み、プログラムだけでなくすべてのプログラムに影響します。あなたがポゴと一緒に暮らすことができないならば、あなたは透明性をあきらめなければならないでしょう。
ハンスとインターネット全体(WPF .... pfffftを学ぶだけ)がここで間違っていることを報告できることを非常に嬉しく思います。
問題は、WM_HSCROLLイベントとWM_VSCROLLイベントにあります。いくつかの試行錯誤の結果、スクロールバーを十分に速くドラッグすると、背景のゴーストコピーを実際の背景の上に移動できることがわかりました。したがって、スクロール可能なコントロール内で何が起こっていても、Windowsはそれに追いつくことができ、同期していない再描画の一部がせん断の原因になります。
では、この問題をどのように解決しますか?
スクロール可能なコントロールをDoubleBufferedに設定します。
WM_HSCROLL/WM_VSCROLLメッセージをキャッチします。無効にします。「do_not_paint」フラグをtrueに設定します。base.WndProc()を呼び出します。「do_not_paint」フラグをfalseに設定します。アップデート。
WM_PAINTおよび関連するメッセージをキャッチします。「do_not_paint」フラグがfalseの場合にのみ、base.WndProc()を呼び出します。
これにより、スクロール可能なコントロールは、必要なレイアウト計算とスクロールバーの再配置を実行できますが、せん断効果をトリガーするものを再描画することはできません。
FlowPanel amdのScrollイベントにApplication.DoEvents()を追加して、取得していたFlowPanel子コントロールのぼかしを停止しました。
少し遅れています...しかし、Color.Transparentをいじると、このようなことが起こります。FlowLayoutPanelに透明な背景があるかどうかを確認します。もしそうなら、それを変更してみてください。