Scroll Panel

28/10/2008 - 23:24 von Thomas Kehl | Report spam
Hallo zusammen.

Ich zeichne Linien und Rechtecke auf ein Panel (mittels dem Paint-Event).
Nun ist es so, dass mein "Kreatur" über den sichtbaren Bereich des Panels
hinausgeht. Ich habe nun mittels AutoScroll und AutoScrollMargin sowie
AutoScrollMinSize die Scrollbars eingeblendet.
Das Problem ist nun, wenn gescrollt wird, wird meine "Kreatur" sehr komisch
gezeichnet. Es wird nicht korrekt refreshd. Wenn ich das Form aus dem
Bildschirm raus und wieder reinziehe, wird das Ganze refreshed, aber so, wie
wenn nicht gescrollt worden wàre.
Kann mir jemand weiterhelfen, wie ich zum Ziel komme? - Muss ich evt.
wàhrend dem Scrollen meine "Kreatur" verschieben (im Paint-Ereignis?)

Danke im Voraus für eure Hilfe!

Herzliche Grüsse, Thomas
 

Lesen sie die antworten

#1 Karsten Sosna
29/10/2008 - 06:42 | Warnen spam
Ich zeichne Linien und Rechtecke auf ein Panel (mittels dem Paint-Event).
Nun ist es so, dass mein "Kreatur" über den sichtbaren Bereich des Panels
hinausgeht. Ich habe nun mittels AutoScroll und AutoScrollMargin sowie
AutoScrollMinSize die Scrollbars eingeblendet.
Das Problem ist nun, wenn gescrollt wird, wird meine "Kreatur" sehr
komisch gezeichnet. Es wird nicht korrekt refreshd. Wenn ich das Form aus
dem Bildschirm raus und wieder reinziehe, wird das Ganze refreshed, aber
so, wie wenn nicht gescrollt worden wàre.
Kann mir jemand weiterhelfen, wie ich zum Ziel komme? - Muss ich evt.
wàhrend dem Scrollen meine "Kreatur" verschieben (im Paint-Ereignis?)



Hier ein Beispiel:

Form1
\\\
Public Class Form1

Friend Panel1 As New Panel
Friend WithEvents BTN_Add As New Button
Friend WithEvents BTN_Remove As New Button

Friend WithEvents ScrollPanel1 As New ScrollPanel

Private Sub Form1_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
ScrollPanel1.Dock = DockStyle.Fill
ScrollPanel1.BackColor = SystemColors.Window
ScrollPanel1.Parent = Me

Panel1.Height = 35
Panel1.Dock = DockStyle.Top
Panel1.Parent = Me

BTN_Add.Location = New Point(5, 5)
BTN_Add.Text = "Add"
BTN_Add.Parent = Panel1

BTN_Remove.Location = New Point(BTN_Add.Width + 10, 5)
BTN_Remove.Text = "Remove"
BTN_Remove.Parent = Panel1

Me.Size = New Size(400, 300)
End Sub

Private Sub BTN_Add_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles BTN_Add.Click
Dim dObj As New DrawingObject
Dim rnd As New Random
If rnd.Next(0, 2) = 0 Then
dObj.DrawingType = DrawingObject.DrawingTypes.Ellipse
Else
dObj.DrawingType = DrawingObject.DrawingTypes.Rect
End If
dObj.Color = Color.FromArgb(rnd.Next(0, 256), rnd.Next(0, 256),
rnd.Next(0, 256))
dObj.Rectangle = New Rectangle(rnd.Next(0, 300), rnd.Next(0, 300),
rnd.Next(20, 500), rnd.Next(20, 500))
ScrollPanel1.AddDrawingObject(dObj)
End Sub

Private Sub BTN_Remove_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles BTN_Remove.Click
If ScrollPanel1.Count > 0 Then
ScrollPanel1.RemoveAtDrawingObject(ScrollPanel1.Count - 1)
End If
End Sub
End Class
///

ScrollPanel
\\\
Public Class ScrollPanel

'Inherits Panel
Inherits ScrollableControl

Private DrawingList As New List(Of DrawingObject)

Public Sub New()
Me.AutoScroll = True
Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or
ControlStyles.OptimizedDoubleBuffer Or ControlStyles.ResizeRedraw Or
ControlStyles.UserPaint, True)
End Sub

Public Sub AddDrawingObject(ByVal drawingObject As DrawingObject)
DrawingList.Add(drawingObject)
SetAutoScrollMinSize()
End Sub

Public Sub RemoveAtDrawingObject(ByVal index As Integer)
DrawingList.RemoveAt(index)
SetAutoScrollMinSize()
End Sub

Public Function Count() As Integer
Return DrawingList.Count
End Function

Private Sub SetAutoScrollMinSize()
If DrawingList.Count = 0 Then
Me.AutoScrollMinSize = Me.Size
Else
Using GP As New Drawing2D.GraphicsPath
For Each dObj In DrawingList
GP.AddRectangle(dObj.Rectangle)
Next
Me.AutoScrollMinSize = New Size(CInt(GP.GetBounds.Right),
CInt(GP.GetBounds.Bottom))
End Using
End If
Me.Invalidate()
End Sub

Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)
'MyBase.OnPaint(e)
e.Graphics.TranslateTransform(Me.DisplayRectangle.X,
Me.DisplayRectangle.Y)
For Each dObj In DrawingList
Using SBR As New SolidBrush(dObj.Color)
Select Case dObj.DrawingType
Case DrawingObject.DrawingTypes.Ellipse
e.Graphics.FillEllipse(SBR, dObj.Rectangle)
Case DrawingObject.DrawingTypes.Rect
e.Graphics.FillRectangle(SBR, dObj.Rectangle)
End Select
End Using
Next
End Sub

Protected Overrides Sub OnPaintBackground(ByVal e As
System.Windows.Forms.PaintEventArgs)
MyBase.OnPaintBackground(e) '<< Diese Zeile mal auskommentieren
End Sub

End Class
///

DrawingObjekt
\\\
Public Class DrawingObject

Public Enum DrawingTypes
Rect
Ellipse
End Enum

Public Rectangle As RectangleF
Public Color As Color
Public DrawingType As DrawingTypes
End Class
///

3 Dinge sind zu beachten. !. Ich habe hier vom ScrollableControl abgeleitet.
Du kannst auch von Panel ableiten, aber das ist überflüssig, wenn Du die
zusàtzlichen Funktionen von Panel nicht brauchst. Panel leitet übrigens auch
nur von ScrollableControl ab. 2. Das Setzen der Styles im Konstructor. Was
die bedeuten siehe bitte in der MSDN. 3. Ich zeichne im OnPaint und nicht im
Paint-Event. Das Warum würde hier etwas zu weit führen, aber eine kurze
Erklàrung: Die erste Zeile im OnPaint ist auskommentiert. Damit wird
erreicht, dass sich die Basisklasse nicht selber zeichnet, brauch sie auch
nicht, denn den Zeichnevorgang will ich ja übernehmen. Das hat zur Folge,
dass auch kein Paint-Event gefeuert wird. Synomym dazu kannst Du das an der
OnPaintBackground-Methode sehen. Im Form_Load-Event habe ich die
BackColor-Eigenschaft des Controls gesetzt(Farbe ist normalerweise Weiß).
Wenn Du jetzt die Zeile "MyBase.OnPaintBackground(e)" mal auskommentierst
wird der Hintergrund nicht mehr gelöscht und bleibt schwarz. Die Basisklasse
übernimmt also das Löschen mit der Hintergrundfarbe. Gleiches gilt für
OnPaint. Ist der Basisklassenaufruf auskommentiert, kann die Basisklasse
auch nicht zeichen.
Der Rest sollte selbsterklàrend sein. Wenn Du noch Fragen hast melde Dich
einfach.
Gruß Scotty

Ähnliche fragen