2016-10-12 10 views
1

2つのエクステントコントロールがあります。 最初にLiveControlと呼ばれ、サイズ変更、回転、移動、...メソッドを持つPictureBoxから継承されています。 第2のものは、Panelから継承されたDrawPanelと呼ばれ、複数のLiveControlの親であることを意図しています。winformのすべてのコントロールを無効にすると、OnPaintメソッドが無期限に呼び出されます

LiveControlが別のものの上を移動したときに、フィラーリングを減らしたり、トレイルを残すためにいくつかのことを行いました。

MouseUp += (s, e) => 
{ 
    foreach (Control c in Parent.Controls.OfType<LiveControl>()) 
     c.Refresh(); 
}; 
MouseMove += (s, e) => 
{ 
    if (e.Button == MouseButtons.Left) 
    { 
     Control x = (Control)s; 
     x.SuspendLayout(); 
     x.Location = new Point(x.Left + e.X - cur.X, x.Top + e.Y - cur.Y); 
     x.ResumeLayout(); 
     foreach (Control c in Parent.Controls.OfType<LiveControl>()) 
      c.Update(); 
    } 
}; 

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 
    foreach (Control c in Parent.Controls.OfType<LiveControl>())     
     c.Invalidate();      
} 

しかし、問題は、上記のコードのように、各 LiveControlOnPaintLiveControl秒のすべてを無効に、それは無限の原因となるということです。そして最終的に私は LiveControlで、次のコードで予想以上に、それはさらに良く達成しました OnPaintの呼び出しは、フォーム上の他のコントロールに問題を引き起こします(遅延が非常に遅くなります)。この問題を解決するには

私はこのようなOnPaintのコードに編集:

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 
    if (!((DrawPanel)Parent).Invalidating) 
    { 
     ((DrawPanel)Parent).Invalidating = true; 
     ((DrawPanel)Parent).InvalidatedCount = 0; 
     foreach (Control c in Parent.Controls.OfType<LiveControl>())     
      c.Invalidate();    
    } 
    else 
    { 
     ((DrawPanel)Parent).InvalidatedCount++; 
     if (((DrawPanel)Parent).InvalidatedCount == ((DrawPanel)Parent).Controls.OfType<LiveControl>().Count()) 
     { 
      ((DrawPanel)Parent).InvalidatedCount = 0; ((DrawPanel)Parent).Invalidating = false; 
     } 
    } 
} 

をしかしOnPaint方法はまだノンストップと呼ばれています。 誰かがこれを解決する方法を知っていますか?

+0

downvoter、あなたはなぜそう言いたいですか? –

+0

OnPaintイベントでペイントイベントをデタッチしようとし、タスクを完了した後に、コントロールで再び登録します。無限ループから克服するのに役立ちます。 –

+0

@NiranjanKala OnPaintイベントをデタッチすると、Invalidate()何でもいい。 –

答えて

1

InvalidateトリガーPaintPaintInvalidateを呼び出すことは無限ループです。それをしないでください!

すべてのコントロールにはDoubleBufferingが表示されます。あなたはサブクラスする必要があるかもしれませんDoublBufferingをオンにするは、そのうちのいくつかは、​​、FlowLayoutPanelsまたはDGVsのような... Infactは唯一Formは、それを公開し、唯一PictureBoxは、デフォルトではそれを持っています。

また、すべてが不要であることを確認する必要があります。Invalidatesが削除されています。 - 通常Invalidateの場合は、データが必要ですが必要です。私はあなたのコードには全く描画が表示されません。そうでなければRefreshに電話して、が裂ける、すなわち「尾」または「痕跡」を取り除く必要が生じることがあります。

1

私はOnPaintを一切扱っていません。私はカスタムペイントをPaintイベントでやってみたいです。

塗料の更新状況では、Invalidate()を決して呼び出さないでください。 Flickerに問題がある場合は、カスタムコントロールとコンテナでDoubleBufferedをtrueに設定しようとしましたか?

DrawPanel.Invalidate()を呼び出してDrawPanelを無効にすると、オーバーライドにはbool invalidateChildrenというフラグが設定されます。あなたは本当にそれを設定しようとしましたか?

希望すると、これが役立ちます。

+0

私は 'DoubleBuffered'を試して、結果を悪化させています。他のコントロールの上にトレイルが残ります。 'DrawPanel.Invalidate()'、 'invalidateChildren'をtrueに設定すると、すべての子が無効になり、親も無効になります。私はPaintイベントで何が起こるかを見るためにそれに対処しようとします。 –

+0

@AshkanMobayenKhiabani:あなたは他のどこかで重大なトラブルに陥っていると思います。私はあなたが何度も何の問題もなく何もしなくても何の問題もなく何もしていないことをやったことがあります。Panelから派生するのではなく、UserControlから派生させようとしましたが、PictureBoxをUserControl同じように? –

関連する問題