@TobiasS
Dein Gedanke mit dem Panel hat leider auch nicht geklappt, es sind einfach zu viele Operationen in zu kurzer Zeit.
@Jonny132
Im Prinzip habe ich es auch so gemacht, wie in dem Link von dir. Mit Ausnahme von CreateGraphics, aber ich bezweifle, dass das das Problem ist. Das Problem beschränkt sich ja nur auf eine Vorschau der zu zeichnenden Objekte, also eine Live-Aktualisierung.
@Ralf
Der Tipp sieht brauchtbar aus, allerdings bekomme ich auch hier das mit der Vorschau nicht hin. Es wird gar nichts neugezeichnet. Ich habe folgenden Code:Public Class PaintBox
Inherits PictureBox
Private AllowDrawing As Boolean
Public Lines As List(Of Line)
Private CurrentLine As Line
Private bmpBack As Bitmap
Public Sub New()
MyBase.New()
MyBase.BackColor = Color.White
MyBase.SetStyle(ControlStyles.UserPaint, True)
MyBase.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
MyBase.SetStyle(ControlStyles.DoubleBuffer, True)
Lines = New List(Of Line)
bmpBack = New Bitmap(Me.Width, Me.Height)
Me.Image = CType(bmpBack.Clone, Drawing.Image)
End Sub
Private Sub Me_MouseDown(ByVal sender As System.Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
AllowDrawing = True
CurrentLine = New Line
CurrentLine.StartPoint = New Point(e.X, e.Y)
Me.SuspendLayout()
Redraw()
End Sub
Private Sub Me_MouseMove(ByVal sender As System.Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
If AllowDrawing Then
CurrentLine.EndPoint = New Point(e.X, e.Y)
Redraw(True)
End If
End Sub
Private Sub Me_MouseUp(ByVal sender As System.Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseUp
AllowDrawing = False
Lines.Add(CurrentLine)
Me.ResumeLayout()
Redraw()
End Sub
Private Sub Me_Resize(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles MyBase.Resize
Dim newbmp As New Bitmap(Me.Width, Me.Height)
Using gr As Graphics = Graphics.FromImage(newbmp)
gr.DrawImage(bmpBack, New Point(0, 0))
End Using
bmpBack = newbmp
End Sub
Public Sub Redraw()
If bmpBack IsNot Nothing Then
Me.Image = CType(bmpBack.Clone, Drawing.Image)
Else
Me.Image = New Bitmap(Me.Width, Me.Height)
Using gr As Graphics = Graphics.FromImage(Me.Image)
gr.Clear(Color.White)
End Using
End If
For Each l In Lines
Using gr As Graphics = Graphics.FromImage(Me.Image)
l.Draw(gr)
End Using
Next
Me.Refresh()
End Sub
Public Sub Redraw(ByVal onlyCurrent As Boolean)
Using gr As Graphics = Graphics.FromImage(Me.Image)
gr.DrawImage(bmpBack, 0, 0, Me.Image.Width, Me.Image.Height)
For Each l In Lines
l.Draw(gr)
Next
End Using
Dim r As Region = GetRegionFromCurrentLine()
Me.Invalidate(r)
Me.Update()
End Sub
Public Function GetRegionFromCurrentLine() As Region
Dim rect As New RectangleF
Using gp As New System.Drawing.Drawing2D.GraphicsPath
gp.AddPolygon(New Point() {CurrentLine.StartPoint, _
CurrentLine.EndPoint, New Point(CurrentLine.EndPoint.X + 5, _
CurrentLine.EndPoint.Y - 5), CurrentLine.StartPoint})
rect = gp.GetBounds
End Using
rect.Inflate(100.0F, 100.0F)
Return New Region(rect)
End Function
End Class
Public Class Line
Public StartPoint As Point
Public EndPoint As Point
Public Color As Color = Drawing.Color.Red
Public Size As Integer = 1
Public Sub Draw(ByVal g As Graphics)
g.DrawLine(New Pen(Color, Size), StartPoint.X, StartPoint.Y, EndPoint.X, _
EndPoint.Y)
End Sub
End Class Ich vermute bei Redraw(boolean) und/oder GetRegionFromCurrentLine wird der Fehler liegen, da nur die Vorschau nicht gezeichnet wird, der Rest schon. Vom Prinzip her ist klar, wie der Tipp funktioniert. Es wird nur der entsprechende Bereich neugezeichnet, aber das will bei mir nicht so gut. Weiß jemand wie ich das damit erledigen kann? |