Results 1 to 7 of 7

Thread: How to make attached title for each drawn shape in a picturebox?

  1. #1

    Thread Starter
    New Member
    Join Date
    Aug 2019
    Posts
    5

    How to make attached title for each drawn shape in a picturebox?

    Dears in VB.net Forum

    How to get in the following solutions:

    1. I need to make attached title/label or text for the drawing shapes in the picturebox, and move them together in the same time? How I can code that problem?
    2. I have zoom factor in the code as in the following, My problem is : I can't zoom from center of the picturebox? How I can modify that in my code:

    ----------------------------------------------------------------

    Public Property Zoom As Single
    Get
    Return _zoom
    End Get
    Set(ByVal value As Single)

    If value < 0 OrElse value < 0.00001 Then
    value = 0.00001F
    End If

    _zoom = value
    'UpdateScaleFactor()
    Invalidate()
    End Set
    End Property
    -----------------------------------------------------------------------------
    If e.Delta > 0 Then 'if delta is 120 wheel is scrolled up, if it is -120 wheel is scrolled down
    Zoom += 0.1F
    Else
    Zoom -= 0.1F
    End If
    If Zoom > 10.0 Then
    Zoom = 10
    End If
    If Zoom < 1 Then
    Zoom = 1
    End If

    ---------------------------------------------------------------


    Thanks,
    Saleh

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: How to make attached title for each drawn shape in a picturebox?

    Please format your code snippets using the tools provided by the editor for the purpose. The indenting makes the code far more readable.
    vb.net Code:
    1. Public Property Zoom As Single
    2.         Get
    3.             Return _zoom
    4.         End Get
    5.         Set(ByVal value As Single)
    6.  
    7.             If value < 0 OrElse value < 0.00001 Then
    8.                 value = 0.00001F
    9.             End If
    10.  
    11.             _zoom = value
    12.             'UpdateScaleFactor()
    13.             Invalidate()
    14.         End Set
    15.     End Property
    vb.net Code:
    1. If e.Delta > 0 Then 'if delta is 120 wheel is scrolled up, if it is -120 wheel is scrolled down
    2.             Zoom += 0.1F
    3.         Else
    4.             Zoom -= 0.1F
    5.         End If
    6.         If Zoom > 10.0 Then
    7.             Zoom = 10
    8.         End If
    9.         If Zoom < 1 Then
    10.             Zoom = 1
    11.         End If

  3. #3
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: How to make attached title for each drawn shape in a picturebox?

    1. How do you draw the shapes in the picturebox? Do you have a Class that keeps track of the shapes? If so, I would think you would add a string to the class, and perhaps a relative offset for the string if you want the string to be positioned at a defined location relative to the shape. You would then draw the string as part of drawing the shape.

    2. We need to know how you are doing your drawing. Normally, to zoom around the center means you have to offset the drawing's upper left coordinate to keep the coordinate that was in the center of the screen at the center of the screen after the zoom operation.
    The basic steps would be.
    a. Determine what X,Y coordinate is at the center of the screen now.
    b. Adjust your zoom value to the new zoom value.
    c. Using the desired X,Y coordinate you want at the center, calculate what the upper left coordinate would be at the current zoom level
    d. Use the calculated upper left coordinate as your upper left coordinate when you draw.

  4. #4

    Thread Starter
    New Member
    Join Date
    Aug 2019
    Posts
    5

    Re: How to make attached title for each drawn shape in a picturebox?

    Thanks Sir for your notification !

    I am gonna do it next time,

    Thanks!

  5. #5

    Thread Starter
    New Member
    Join Date
    Aug 2019
    Posts
    5

    Re: How to make attached title for each drawn shape in a picturebox?

    Quote Originally Posted by passel View Post
    1. How do you draw the shapes in the picturebox? Do you have a Class that keeps track of the shapes? If so, I would think you would add a string to the class, and perhaps a relative offset for the string if you want the string to be positioned at a defined location relative to the shape. You would then draw the string as part of drawing the shape.

    2. We need to know how you are doing your drawing. Normally, to zoom around the center means you have to offset the drawing's upper left coordinate to keep the coordinate that was in the center of the screen at the center of the screen after the zoom operation.
    The basic steps would be.
    a. Determine what X,Y coordinate is at the center of the screen now.
    b. Adjust your zoom value to the new zoom value.
    c. Using the desired X,Y coordinate you want at the center, calculate what the upper left coordinate would be at the current zoom level
    d. Use the calculated upper left coordinate as your upper left coordinate when you draw.
    Thanks passel for your reply, actually Yes, I have class for shapes that I keep in track for drawing but unfortunately that I am not able to build string to the class, I have no idea how, I will try to copy the shape class for you in the following:

    Code:
    Public Class Shape
        Implements IDisposable
    
        Public Shared Function GetPolygonPoints(ByVal radius As Integer, ByVal sides As Integer, ByVal position As PointF) As PointF()
            Dim points(sides - 1) As PointF
            For side As Integer = 0 To sides - 1
                Dim delta As Single = Math.PI / sides + side * 2 * Math.PI / sides
                points(side) = New PointF(position.X + radius * CSng(Math.Sin(delta)), position.Y + radius * CSng(Math.Cos(delta)))
            Next
            Return points
        End Function
    
    
        Private _Brush As System.Drawing.Brush
        Public Property Brush() As Brush
            Get
                Return _Brush
            End Get
            Set(ByVal value As Brush)
                _Brush = value
            End Set
        End Property
    
        Public Property FillColor As Color = Color.White
    
        Private _Font As Font
        Public Property Font() As Font
            Get
                Return _Font
            End Get
            Set(ByVal value As Font)
                _Font = value
            End Set
        End Property
    
        Public Property LineColor As Color = Color.Black
        Public Property LineWidth As Single = 0.1!
        Public Property Width As Single
        Public Property Height As Single
    
        Protected _Path As System.Drawing.Drawing2D.GraphicsPath
        Public ReadOnly Property Path As System.Drawing.Drawing2D.GraphicsPath
            Get
                Return _Path
            End Get
        End Property
    
        Private _Position As PointF
        Public Property Position() As PointF
            Get
                Return _Position
            End Get
            Set(ByVal value As PointF)
                If Not _Position = value Then
                    Dim oldPosition As PointF = _Position
                    _Position = value
                    PositionPath(oldPosition)
                End If
            End Set
        End Property
    
        Public Property radius() As Integer
    
        Protected Friend _picturebox As picturebox
        Public ReadOnly Property picturebox As picturebox
            Get
                Return _picturebox
            End Get
        End Property
    
        Protected _Sides As Integer
        Public ReadOnly Property Sides As Integer
            Get
                Return _Sides
            End Get
        End Property
    
        Protected _Size As Integer
        Public ReadOnly Property Size As Integer
            Get
                Return _Size
            End Get
        End Property
    
        Private _Text As String
        Public Property Text() As String
            Get
                Return _Text
            End Get
            Set(ByVal value As String)
                If value Is Nothing Then value = String.Empty
                _Text = value
            End Set
        End Property
    
        Private _TextFormat As StringFormat
        Public Property TextFormat() As StringFormat
            Get
                Return _TextFormat
            End Get
            Set(ByVal value As StringFormat)
                _TextFormat = value
            End Set
        End Property
    
        Public Property TextColor As Color = Color.Black
    
        Public Sub New(ByVal sides As Integer, ByVal radius As Integer, ByVal x As Single, ByVal y As Single)
    
            '.Text = InputBox("Enter the Name", "")
            _TextFormat = New StringFormat
            _TextFormat.Alignment = StringAlignment.Center
            _TextFormat.LineAlignment = StringAlignment.Center
            _Sides = sides
            Me.radius = radius
            _Position = New PointF(x, y)
            _Path = New System.Drawing.Drawing2D.GraphicsPath
            If sides = 0 Then
                _Path.AddEllipse(x - radius, y - radius, radius * 2, radius * 2)
            ElseIf sides = 1 Then
                _Path.AddLine(x - radius, y + radius, x + radius, y + radius)
            ElseIf sides = 2 Then
                _Path.AddLine(x + radius, y - radius, x + radius, y + radius)
            Else
                _Path.AddLines(Shape.GetPolygonPoints(radius, sides, New PointF(x, y)))
                '_Path.AddString(_Text, _Font, _Brush, _Size, x, y)
            End If
            _Path.CloseFigure()
            _Font = New Font("Arial", 10)
            _Text = String.Empty
        End Sub
    
        Public Function BringForward() As Integer
            Dim index As Integer = -1
            If _picturebox IsNot Nothing Then
                index = _picturebox._Shapes.IndexOf(Me)
                If index > -1 Then
                    index = _picturebox._Shapes.BringForward(index)
                End If
            End If
            Return index
        End Function
    
        Public Function BringToFront() As Boolean
            Dim index As Integer = _picturebox._Shapes.IndexOf(Me)
            If _picturebox IsNot Nothing AndAlso index > -1 Then
                Return _picturebox._Shapes.BringToFront(index)
            End If
            Return False
        End Function
    
        Public Function SendBackward() As Integer
            Dim index As Integer = -1
            If _picturebox IsNot Nothing Then
                index = _picturebox._Shapes.IndexOf(Me)
                If index > -1 Then
                    index = _picturebox._Shapes.SendBackward(index)
                End If
            End If
            Return index
        End Function
    
        Public Function SendToBack() As Boolean
            Dim index As Integer = _picturebox._Shapes.IndexOf(Me)
            If _picturebox IsNot Nothing AndAlso index > -1 Then
                Return _picturebox._Shapes.SendToBack(index)
            End If
            Return False
        End Function
    
        Public Function GetBounds() As RectangleF
            Dim currentbounds As RectangleF = _Path.GetBounds
            If currentbounds.Width < 1 Then currentbounds.Inflate(4.0F, 0.0F)
            If currentbounds.Height < 1 Then currentbounds.Inflate(0.0F, 4.0F)
            Return currentbounds
        End Function
    
        Public Sub UpdatePosition()
            If Not disposedValue Then
                _Position = CType(_Path.GetBounds.Location, PointF)
            End If
        End Sub
    
        Protected Friend Sub Draw(ByVal e As System.Windows.Forms.PaintEventArgs)
            'Dim TextColor1 As Color = Color.Black
            'Dim _font1 As New Font("Arial", 10)
            'Dim _TextFormat1 As StringFormat = StringFormat.GenericDefault
            'Dim textBrush1 As New SolidBrush(TextColor)
    
    
            If Not disposedValue Then
                'e.Graphics.DrawString(InputBox("dsadasda", ""), _font1, textBrush1, 300, 300, _TextFormat1)
    
                Using fillBrush As New SolidBrush(FillColor)
                    e.Graphics.FillPath(fillBrush, _Path)
                End Using
                If LineWidth > 0 Then
                    Using linePen As New Pen(LineColor, LineWidth)
                        e.Graphics.DrawPath(linePen, _Path)
                    End Using
                End If
                If _Text.Length > 0 Then
                    Dim bounds As RectangleF = GetBounds()
                    Using textBrush As New SolidBrush(TextColor)
                        e.Graphics.DrawString(InputBox("dsadasda", ""), _Font, textBrush, bounds, _TextFormat)
                    End Using
                End If
            End If
        End Sub
    
    
        Protected Sub PositionPath(ByVal oldPosition As PointF)
            If Not disposedValue Then
                Dim translation As New System.Drawing.Drawing2D.Matrix()
                translation.Translate(_Position.X - oldPosition.X, _Position.Y - oldPosition.Y)
                'translation.Scale(TrackBar.MousePosition.X, TrackBar.MousePosition.Y)
                _Path.Transform(translation)
                translation.Dispose()
            End If
        End Sub

  6. #6

    Thread Starter
    New Member
    Join Date
    Aug 2019
    Posts
    5

    Re: How to make attached title for each drawn shape in a picturebox?

    I have another question in the same concept,

    How to connect two shapes with polyline in the picturebox? and to assign the start point and end point snapped to my shapes? Also if I move the shapes, then the line at end and start can be moved also belonging to the shapes as moving (shapes are Linked together by line)? it is part of scheme drawing project that I am demanding to make by VB.NET and Picturebox GDI+ Drawing.


    Is there any possibility for you to help doing this functionality by Code?

    Many thanks!

  7. #7
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: How to make attached title for each drawn shape in a picturebox?

    It looks like your have code to draw a string, but you're referencing an Inputbox rather than drawing the _Text string that is part of the shape. Looks like debug/test code. I assume if you set the _Text property to a string, it should be drawing that string "on top" of your shape, in the upper left corner of the rectangle you're passing.

    I don't really have the time to help that much. Depending on how you want to draw the lines it can be complex to route the lines.
    When I had an application that had to have various size rectangles showing connections that the user could change, and the layout of the rectangles and dimensions could be modified by the user, I just went with a simple approach and drew straight lines from the center of one rectangle to the other to show the connections.

    In my case, there was somewhat of a hierarchy to the connections, so I drew the connecting lines in three passes. But, I also drew all the connecting lines first, and then drew the "shapes" so that while the lines endpoints were technically the center of the rectangles, they appeared to stop at the boundary of the rectangle because the filled rectangles were drawn on top of the connecting lines, so obscured the portion of the line from the edge of the shape to the center.

    As for the hierarchy of the connecting lines, what I was drawing were port connections on an Ethernet switch to Virtual Lans, so at any give time, the user may have a particular Vlan selected and a particular port selected. The connection lines from ports to Vlans were drawn in three passes. First all the lines that were not part of the selected Vlan were drawn in blue, just to show the connections, but not make them stand out. Then, all the lines from ports to the selected Vlan were drawn in Cyan to make them standout from the other connections (and they were drawn second so drew "over" the blue lines). Last, the connection line from the Selected Port to the Selected Vlan was drawn in Yellow to make it standout from all the other connections, and the labels in the readout area, i.e. port number, name, description, etc... were for that selected port.

    The connected shapes just had an entry in their class, to store a reference to another shape if there was a connection.
    The connection draw code looked like this.
    Code:
      Public Sub DrawConnections(ByVal g As Graphics)
        Dim iport As Integer = portStack
        Dim iportIdx As Integer = -1
        Dim vlanList As New List(Of Integer)
    
        Do While iport <> -1
          With portObjs(iport)
            If .vLan <> -1 Then
              If iport = SelectedPort Then
                iportIdx = iport   'Save to draw Last
              ElseIf .vLan = SelectedVlan Then
                vlanList.Add(iport) 'Save to draw after unselected connections 'c = PortVlanPen
              Else
                DrawConnection(g, Pens.Blue, iport)  'Draw the unselected items first (bottom layer)
              End If
            End If
          End With
          iport = portObjs(iport).nextObj
        Loop
    
        For Each i As Integer In vlanList
          DrawConnection(g, PortVlanPen, i)  'Draw the selected vLan connections next (middle layer)
        Next
    
        If iportIdx <> -1 Then
          DrawConnection(g, SelPortPen, iportIdx) 'Draw the selected port connection last (top layer)
        End If
      End Sub
    The first main loop is going through all the ports looking for connections. It checks if the port being checked is the selected port, and if so saves that port to draw its connection last (and in a different color).
    If it isn't the currently selected port, it next checks to see if the connection is to the currently selected VLan. If it is, it adds the port to a list to be drawn later.
    Finally, if it is neither of those cases, then it draws the connection using the default (Blue) color.
    Once all the blue connections are drawn, then the loop through the list of active vlan connections is drawn in Cyan, and then finally the current port connection is drawn with a yellow connection.

    As I said, the connection lines were drawn before the shapes. The routine above that drew the connections was called second, in a series of drawing levels. That upperlevel code looked like this.
    Code:
          DrawBackgroundObjs(e.Graphics)
          DrawConnections(e.Graphics)
          DrawVlans(e.Graphics)
          DrawPorts(e.Graphics)
    So, there were background objects to be draw that were "below" all other shapes and connection lines.
    Then the connection lines were drawn.
    Then the Vlan shapes were drawn "on Top" of the connection lines, followed by the port shapes being drawn last. These were all called from the Paint event of course (i.e. why e.Graphics was passed to each sub).

    p.s. Looking back at the code I posted, I see I didn't actually show the drawing code itself. The loops call a sub called DrawConnection which does the actual drawing. I'll include it as you may wonder what was in that sub. But, it is as I described. You'll see a lot of divide by 2 height and width calculations to find the center of the source (Port shape) and destination (Vlan Shape) rectangles and then draws a line connecting those two points using the Pen passed. The port is passed, and the Vlan (the connection) is retrieved from the port object.
    Code:
      Private Sub DrawConnection(ByVal g As Graphics, ByVal p As Pen, ByVal port As Integer)
        With portObjs(port)
          g.DrawLine(p, .PosRect.X + .PosRect.Width \ 2, .PosRect.Y + .PosRect.Height \ 2,
               vLanObjs(.vLan).PosRect.X + vLanObjs(.vLan).PosRect.Width \ 2,
         vLanObjs(.vLan).PosRect.Y + vLanObjs(.vLan).PosRect.Height \ 2)
        End With
      End Sub
    Last edited by passel; Aug 7th, 2019 at 10:40 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width