Benutzer mit den meisten Antworten
[VB2005] Frage zu Panel, Size <--> ClientSize

Frage
-
Hi Leute.
Eine kurze aber doch recht grundsätzliche Frage zu Frames: Angenommen ich habe ein Frame von 100x100 Pixeln (entspricht vll. einem Client-Size von 90x90, wegen Abzügen durch Scrollbars und so), will aber in diesem einen scrollbaren Inhalt von 500x500 anzeigen. Nun überschreib ich die OnPaint und male dort ein 500x500 großes Bild. Aber wie sag ich dem Control (Panel), dass sein eigentlicher Inhalt nicht 100x100 ist, sondern 500x500?
Weil ich bekomme ja so erstmal keine Scrollbars. Und Size ist ja Teil von Bounds, sprich dem Außenrechteck, also dem des Controls, nicht seines (virtuellen) Inhaltes. Und ClientRectangle isses auch nicht (das ist doch der Ausschnitt innerhalb des Controls, also ca. 90x90). Ich frage mich, "wessen Size" ich dann manipulieren muss, damit das blöde Ding endlich die Scrollbars anzeigt bzw. richtig einstellt, so dass ich auch wirklich auf 500x500 rumscrollen kann.
Kann mir da einer helfen?
Als Krücke hab ich anfangs ein kleines eingebettetes Control eingefügt (irgend ne Picturebox oder so, Größe 1x1), das einfach auf 500x500 positioniert war. Dann klappte es und ich bekam Scrollbars angezeigt. Aber das wäre doch ein schlechter Witz, wenn es nur so gehen würde. :-)
LG, Dennis.
Antworten
-
Hallo,
wenn Du AutoScroll aktivierst, bestimmt sich die Größe über die AutoScrollMinSize.
Als Beispiel mal ein Control, das ich für ein Testprojekt gebastelt hatte, um Bitmaps anzuzeigen und optional die Anzeige zu skalieren:
Imports System.ComponentModel Imports System.Drawing Imports System.Drawing.Drawing2D Imports System.Windows.Forms Namespace ElmarBoye.Samples.Forms Public Class BitmapPanel Inherits System.Windows.Forms.Panel Private _bitmap As Bitmap Private _zoom As Single Public Sub New() MyBase.SetStyle(ControlStyles.ResizeRedraw, True) MyBase.SetStyle(ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint, True) MyBase.AutoScroll = True Me._zoom = 1F End Sub <DefaultValue(1F)> _ Public Property Zoom() As Single Get Return Me._zoom End Get Set If Me._zoom <> value Then Me._zoom = value Me.ZoomBitmap() End If End Set End Property <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _ Public Property Bitmap() As Bitmap Get Return Me._bitmap End Get Set If Me._bitmap IsNot value Then Me._bitmap = value Me._zoom = 1F Me.ZoomBitmap() End If End Set End Property Private Sub ZoomBitmap() If Me.Bitmap IsNot Nothing Then MyBase.AutoScrollMinSize = New Size( _ CInt(Math.Truncate(Me.Bitmap.Width * Me.Zoom)), _ CInt(Math.Truncate(Me.Bitmap.Height * Me.Zoom))) Else MyBase.AutoScrollMinSize = Size.Empty End If Me.Invalidate() End Sub Protected Overrides Sub OnPaint(e As PaintEventArgs) MyBase.OnPaint(e) If Me.Bitmap IsNot Nothing Then e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic Dim bounds As New Rectangle( _ CInt(Math.Truncate(Math.Floor(-MyBase.AutoScrollPosition.X / Me.Zoom))), _ CInt(Math.Truncate(Math.Floor(-MyBase.AutoScrollPosition.Y / Me.Zoom))), _ CInt(Math.Truncate(Math.Ceiling(MyBase.DisplayRectangle.Width / Me.Zoom))), _ CInt(Math.Truncate(Math.Ceiling(MyBase.DisplayRectangle.Height / Me.Zoom)))) e.Graphics.DrawImage(Me.Bitmap, _ New Rectangle(Point.Empty, MyBase.DisplayRectangle.Size), _ bounds, _ GraphicsUnit.Pixel) End If End Sub Protected Overrides Sub OnDoubleClick(e As EventArgs) MyBase.OnDoubleClick(e) If Not MyBase.DesignMode AndAlso Me.Bitmap IsNot Nothing Then If Me.Zoom <> 1F Then MyBase.AutoScrollMinSize = Me.Bitmap.Size Me.Zoom = 1F Else Dim panelScale As Double = CDbl(Me.Width) / CDbl(Me.Height) Dim bitmapScale As Double = CDbl(Me.Bitmap.Width) / CDbl(Me.Bitmap.Height) Dim zoom As Double = If((bitmapScale >= panelScale), _ CDbl(MyBase.Width) / CDbl(Me.Width), _ CDbl(MyBase.Height) / CDbl(Me.Bitmap.Height)) Me.Zoom = CSng(zoom) End If End If End Sub End Class End Namespace
Evtl. kannst Du Du Dir daraus einiges abgucken.Gruß Elmar
- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 21. Dezember 2011 16:29
Alle Antworten
-
Hallo,
wenn Du AutoScroll aktivierst, bestimmt sich die Größe über die AutoScrollMinSize.
Als Beispiel mal ein Control, das ich für ein Testprojekt gebastelt hatte, um Bitmaps anzuzeigen und optional die Anzeige zu skalieren:
Imports System.ComponentModel Imports System.Drawing Imports System.Drawing.Drawing2D Imports System.Windows.Forms Namespace ElmarBoye.Samples.Forms Public Class BitmapPanel Inherits System.Windows.Forms.Panel Private _bitmap As Bitmap Private _zoom As Single Public Sub New() MyBase.SetStyle(ControlStyles.ResizeRedraw, True) MyBase.SetStyle(ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint, True) MyBase.AutoScroll = True Me._zoom = 1F End Sub <DefaultValue(1F)> _ Public Property Zoom() As Single Get Return Me._zoom End Get Set If Me._zoom <> value Then Me._zoom = value Me.ZoomBitmap() End If End Set End Property <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _ Public Property Bitmap() As Bitmap Get Return Me._bitmap End Get Set If Me._bitmap IsNot value Then Me._bitmap = value Me._zoom = 1F Me.ZoomBitmap() End If End Set End Property Private Sub ZoomBitmap() If Me.Bitmap IsNot Nothing Then MyBase.AutoScrollMinSize = New Size( _ CInt(Math.Truncate(Me.Bitmap.Width * Me.Zoom)), _ CInt(Math.Truncate(Me.Bitmap.Height * Me.Zoom))) Else MyBase.AutoScrollMinSize = Size.Empty End If Me.Invalidate() End Sub Protected Overrides Sub OnPaint(e As PaintEventArgs) MyBase.OnPaint(e) If Me.Bitmap IsNot Nothing Then e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic Dim bounds As New Rectangle( _ CInt(Math.Truncate(Math.Floor(-MyBase.AutoScrollPosition.X / Me.Zoom))), _ CInt(Math.Truncate(Math.Floor(-MyBase.AutoScrollPosition.Y / Me.Zoom))), _ CInt(Math.Truncate(Math.Ceiling(MyBase.DisplayRectangle.Width / Me.Zoom))), _ CInt(Math.Truncate(Math.Ceiling(MyBase.DisplayRectangle.Height / Me.Zoom)))) e.Graphics.DrawImage(Me.Bitmap, _ New Rectangle(Point.Empty, MyBase.DisplayRectangle.Size), _ bounds, _ GraphicsUnit.Pixel) End If End Sub Protected Overrides Sub OnDoubleClick(e As EventArgs) MyBase.OnDoubleClick(e) If Not MyBase.DesignMode AndAlso Me.Bitmap IsNot Nothing Then If Me.Zoom <> 1F Then MyBase.AutoScrollMinSize = Me.Bitmap.Size Me.Zoom = 1F Else Dim panelScale As Double = CDbl(Me.Width) / CDbl(Me.Height) Dim bitmapScale As Double = CDbl(Me.Bitmap.Width) / CDbl(Me.Bitmap.Height) Dim zoom As Double = If((bitmapScale >= panelScale), _ CDbl(MyBase.Width) / CDbl(Me.Width), _ CDbl(MyBase.Height) / CDbl(Me.Bitmap.Height)) Me.Zoom = CSng(zoom) End If End If End Sub End Class End Namespace
Evtl. kannst Du Du Dir daraus einiges abgucken.Gruß Elmar
- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 21. Dezember 2011 16:29
-
Hi Elmar,
das probiere ich mal aus, ob das nur mit Autosize und ohne "Hilfscontrols" klappt. Danke dir.
Ich gehe aber mal davon aus, dass dann die linke obere Ecke immer (0,0) ist und AutoScrollMinSize halt die maximale Ausdehnung des be'scroll'ten Bereichs. Oder kann man da auch ein anderes Eckoffset verwenden als (0,0)? Im Zweifelsfall muss ich dann immer umrechnen auf Fensterkoordinaten, denke ich.
LG, Dennis.
-
Hallo Dennis Becker,
Ich gehe davon aus, dass die Antwort Dir weitergeholfen hat.
Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.Grüße,
RobertRobert Breitenhofer, MICROSOFT
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.