2

2つのプロジェクトで簡単なソリューションを作成しました。最初のプロジェクト(クラスライブラリ)には、丸みを帯びた角でそれ自体を描画するContainerと呼ばれるカスタムコントロールが含まれています。2番目のプロジェクト(Windowsフォーム)はテストアプリケーションです。

2番目のプロジェクトのメインフォームにContainerインスタンスを追加すると、丸みを帯びた角がきれいに表示されます。また、2番目のプロジェクトを実行すると、コンテナーが表示されます。

ただし、フォームの移動を開始すると(タイトルバーをクリックして押したままにする)、特に非常に高速に移動すると、すべての描画が台無しになり、何度も何度も描画されますが、最初に表面がクリアされません...

Form1.MoveイベントでContainer1.Refresh()を呼び出すことはできますが、これを毎回設定する必要はありません。これは、イベントでContainer1.Refresh()を呼び出す必要がForm1.Resizeあり、他のどのイベントを知っているかを意味するためです。 。

コンテナ(コントロール)クラス自体に、Me.Refresh()またはMe.Update()またはMe.Invalidate()を呼び出す必要があるイベントがありますか?

参考までに(Form1.vb)

Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

End Sub

Private Sub Form1_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move
    Me.Container1.Refresh()
End Sub
End Class

参考のために(Container.vb):

Imports System.Windows.Forms
Imports System.Drawing
Imports System.Drawing.Drawing2D

Public Class Container : Inherits Control
    Private _Gp As GraphicsPath

    Private Sub Container_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

        Dim r As Rectangle = e.ClipRectangle
        Dim gp As New GraphicsPath
        Dim cs As Integer = 25 'CornerSize'

        r.Inflate(-5, -5)

        gp.AddArc(r.X, r.Y, cs, cs, 180, 90)
        gp.AddArc(r.X + r.Width - cs, r.Y, cs, cs, 270, 90)
        gp.AddArc(r.X + r.Width - cs, r.Y + r.Height - cs, cs, cs, 0, 90)
        gp.AddArc(r.X, r.Y + r.Height - cs, cs, cs, 90, 90)

        Dim t As Single = cs / 2 + r.Y
        gp.AddLine(r.X, r.Y + r.Height - cs, r.X, t)

        e.Graphics.SmoothingMode = Drawing.Drawing2D.SmoothingMode.AntiAlias
        e.Graphics.DrawPath(Pens.Black, gp)
    End Sub

End Class
4

3 に答える 3

5

これはあなたの問題です:

Dim r As Rectangle = e.ClipRectangle

次のように変更します。

Dim r As Rectangle = Me.ClientRectangle
于 2009-02-09T17:44:26.007 に答える
1

コントロールが微調整されるとすぐに再描画が自動的に強制されるため、(通常の状況では) ここで再描画を強制する必要はありません。

ただし、何かを描画する前に、コントロールの背景をクリアする必要があります。そうしないと、描画操作が以前の描画プロセスと混ざり合ってしまいます。を追加するだけです

e.Graphics.Clear(BackColor)

Paintイベントハンドラーで他​​の描画操作の前に。また、コントロールをサブクラス化し、イベント ハンドラーに頼る必要がないためOnPaint、イベントではなくメソッドを使用することを検討してください。PaintPaint

記録のために、Refresh通常は望ましくない同期再描画を強制します。むしろ、Invalidate再描画要求をデフォルトのウィンドウ メッセージ キューにエンキューする which を使用してください。

于 2009-02-09T10:07:57.367 に答える