Results 1 to 11 of 11

Thread: Programming an editable graphic in VB Forms Application

  1. #1

    Thread Starter
    Member
    Join Date
    Dec 2011
    Location
    Columbus, Ohio
    Posts
    47

    Programming an editable graphic in VB Forms Application

    I have a request to build an element in a VB.net application using graphics. This is an area I am not familiar with and hoping someone can point me in a direction for research and coding examples.

    The concept is a locked down graph with x and y axis and the allowing of a dot to be moved into the graph anywhere in the frame. It can be above or below, right or left of the axis lines, or dead center, or on any one line like below.

    Name:  Grid.png
Views: 883
Size:  28.8 KB

    The location of the dot within the axis means something to the user.

    Dot needs to be a consistent size which makes me wonder if I could drag and drop something I pre-define
    I need to either store the graphic or maybe the coordinates in a database record
    I need to be able to re-animate the graphic so the dot can be moved in an edit and saved again in the database

    Been playing with an idea to stack radio buttons with hard drawn lines on a form to simulate the graph but user asking for overlapping radio buttons so dot can be on the line or touching the line. It is getting really complex.

    Is there a control or something out there that can get me close to the requirements? Any direction or ideas would be appreciated.

    Douglas

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Programming an editable graphic in VB Forms Application

    Take a look at the GraphicsPath class. This is pretty convenient for drawing things that you want to interact with. The interaction may not be all that obvious. It's the IsOutlineVisible method.

    Basically, you create your create your circle (AddEllipse) in your GraphicsPath, and hold that somewhere. In the Paint event of the form, you draw it to the screen with the Graphics object that is part of the e argument of the Paint event:

    e.Graphics.DrawPath()

    If you look at that AddEllipse method, you can see that it takes a rectangle, which is the bounding box of the circle. You could just save that, which would allow you to recreate as needed.
    My usual boring signature: Nothing

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

    Re: Programming an editable graphic in VB Forms Application

    Not to say that anything Shaggy has said is wrong and that this is inherently better but you may like to follow the CodeBank link in my signature below and check out my thread on Manipulating GDI+ Drawings. You may be able to combine what I've done there with what Shaggy has suggested.

  4. #4

    Thread Starter
    Member
    Join Date
    Dec 2011
    Location
    Columbus, Ohio
    Posts
    47

    Re: Programming an editable graphic in VB Forms Application

    Thank you both. That gives me a direction. I will look at these and try them out in detail tomorrow.

  5. #5
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Re: Programming an editable graphic in VB Forms Application

    Quote Originally Posted by Shaggy Hiker View Post
    Take a look at the GraphicsPath class. This is pretty convenient for drawing things that you want to interact with. The interaction may not be all that obvious. It's the IsOutlineVisible method.
    You need IsVisible for hit-testing the dot, not IsOutlineVisible.

    So I hope it's not too late to save you from wasting time wondering what color to choose for the Pen argument (answer: any color, it's ignored).

    BB

  6. #6
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Programming an editable graphic in VB Forms Application

    Actually, IsOutlineVisible and IsVisible are both worth taking a look at. I thought I was using IsOutlineVisible, and I see that I am. However, thinking back over the uses I have...I'm not sure that I ever use closed polygons.
    Last edited by Shaggy Hiker; Jan 28th, 2021 at 10:46 AM.
    My usual boring signature: Nothing

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

    Re: Programming an editable graphic in VB Forms Application

    Quote Originally Posted by DMoody007 View Post
    ...

    The location of the dot within the axis means something to the user.

    I need to either store the graphic or maybe the coordinates in a database record
    I need to be able to re-animate the graphic so the dot can be moved in an edit and saved again in the database
    ...
    I guess some questions would be "The location of the dot...means something", is that only a visual meaning, i.e. the method of positioning the dot and the coordinates used don't matter, as long as you can replicate the image with the dot in a specified position?
    Because it looks like perhaps the dot should align with a limited number of positions, i.e. you have a 7x7 array of circles within the box, with five additional circles, one at the center of the grid, and four tangent to the sides of the center of the grid, and four outside the box, at the corners.

    So, the four at the outer corners of the bounding box, are not aligned at the same spacing as the 49 inside the box, and of course, the five in the center of the box are also not aligned with the other 49 positions inside the box.

    Is the dot position suppose to snap to those position, or be allowed to be placed anywhere?
    Also, do you plot only one dot on the grid, or need to support multiple dots?

    If it is only one dot on the grid, and the dot has to snap to the grid positions, then you wouldn't necessarily have to do hit testing on the dot. You can just find if you've clicked in one of the enumerated positions and if clicking or dragging in the center where you have overlapping circles, which is the closest.

    Assuming the above is the case, here is an example that defines the center position of each of the circles, based on the definition of the radius size, and adds them to a list. The example can then compare the X,Y position of the Mouse in the MouseDown and MouseMove events to determine if the position is inside one of the circles, and save the index of where it was found in the list as the "coordinate" of the dot, i.e. an enumerated position value.

    It uses the radius value, and the list of circle positions to draw the grid.
    Your example showed the grid being drawn over the dot, so the example also draws the dot first, and then the grid when the paint event occurs.
    The paint event is triggered by the code whenever the "coordinate" index value changes.

    Just start a new project, and paste the code below into it to try it out.
    Code:
    Public Class Form1
        Dim Radius As Integer = 30
    
        Private DotPositions As New List(Of Point)
        Private Boundary As Rectangle
        Private CurrentDotIndex As Integer
        Private WithEvents GridBox As New PictureBox
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            DefineGrid()
    
            GridBox.BackColor = Color.White
            GridBox.Location = New Point(10, 10)
            GridBox.Size = Boundary.Size + New Size(3.5 * Radius, 3.5 * Radius)
            GridBox.Visible = True
            Me.Controls.Add(GridBox)
        End Sub
    
        Private Sub DefineGrid()
            Dim p As Point
            Dim sqr2 As Double = Math.Sin(Math.PI / 4)  'sine of 45 degrees, i.e. 0.7071...
    
            'upper Left (center of upperleft circle)
            p.X = Radius
            p.Y = Radius
            DotPositions.Add(p)
    
            'Boundary of graph box
            Boundary.Location = p + New Size(sqr2 * Radius, sqr2 * Radius)
            Boundary.Size = New Point(14 * Radius, 14 * Radius)
    
            'upper Right circle
            p.X = Boundary.X + Boundary.Width + sqr2 * Radius
            DotPositions.Add(p)
    
            'lower Left circle
            p.Y = p.X
            p.X = Radius
            DotPositions.Add(p)
    
            'lower right circle
            p.X = p.Y
            DotPositions.Add(p)
    
            'draw "grid" of background circles
            Dim x As Integer, y As Integer
            Dim lx As Integer, ty As Integer
            lx = Boundary.X + Radius
            ty = Boundary.Y + Radius
            For y = 0 To 6
                p.Y = ty + y * (2 * Radius)
                For x = 0 To 6
                    p.X = lx + x * (2 * Radius)
                    DotPositions.Add(p)
                Next
            Next
    
            Dim center As Integer = Boundary.X + 7 * Radius
            p.X = center
            p.Y = center
            DotPositions.Add(p)    'Center Circle
            CurrentDotIndex = DotPositions.Count - 1
    
            p.X = center - Radius
            p.Y = center - Radius
            DotPositions.Add(p)     'UpperLeft Center
    
            p.X = center + Radius
            DotPositions.Add(p)     'UpperRight Center
    
            p.Y = center + Radius
            DotPositions.Add(p)     'LowerRight Center
    
            p.X = center - Radius
            DotPositions.Add(p)     'LowerLeft Center
        End Sub
    
        Private Sub GridBox_Paint(sender As Object, e As PaintEventArgs) Handles GridBox.Paint
            DrawDot(e.Graphics)
            DrawGrid(e.Graphics)
        End Sub
    
        Private Sub DrawDot(g As Graphics)
            With DotPositions(CurrentDotIndex)
                g.FillEllipse(Brushes.Blue, .X - Radius, .Y - Radius, 2 * Radius, 2 * Radius)
            End With
        End Sub
    
        Private Sub DrawGrid(g As Graphics)
            For Each p As Point In DotPositions
                g.DrawEllipse(Pens.LightBlue, New Rectangle(p.X - Radius, p.Y - Radius, 2 * Radius, 2 * Radius))
            Next
            For i As Integer = DotPositions.Count - 5 To DotPositions.Count - 1
                With DotPositions(i)
                    g.DrawEllipse(Pens.LightGreen, New Rectangle(.X - Radius, .Y - Radius, 2 * Radius, 2 * Radius))
                End With
            Next
            g.DrawRectangle(Pens.Blue, Boundary)
            Using p As New Pen(Brushes.Black, 3)
                Dim center As Integer = Boundary.X + 7 * Radius
                g.DrawLine(p, center, DotPositions(0).Y, center, DotPositions(2).Y)
                g.DrawLine(p, DotPositions(0).X, center, DotPositions(1).X, center)
            End Using
        End Sub
    
        Function FindDotIndex(x As Integer, y As Integer) As Integer
            Static DistanceLimit As Integer = Radius * Radius
            Dim Idx As Integer = -1
            Dim Dist, dx, dy As Integer
            Dim LeastDist As Integer = DistanceLimit
    
            For i = 0 To DotPositions.Count - 1
                With DotPositions(i)
                    dx = x - .X
                    dy = y - .Y
                End With
                Dist = dx * dx + dy * dy
                If Dist < LeastDist Then
                    LeastDist = Dist
                    Idx = i
                End If
            Next
    
            Return Idx
        End Function
    
        Private Sub DotPositionUpdate(x As Integer, y As Integer)
            Dim newIdx As Integer = FindDotIndex(x, y)
    
            If newIdx <> -1 Then
                If newIdx <> CurrentDotIndex Then
                    CurrentDotIndex = newIdx
                    GridBox.Invalidate()
                End If
            End If
        End Sub
    
        Private Sub GridBox_MouseDown(sender As Object, e As MouseEventArgs) Handles GridBox.MouseDown
            DotPositionUpdate(e.X, e.Y)
        End Sub
    
        Private Sub GridBox_MouseMove(sender As Object, e As MouseEventArgs) Handles GridBox.MouseMove
            If e.Button = MouseButtons.Left Then
                DotPositionUpdate(e.X, e.Y)
            End If
        End Sub
    End Class
    Last edited by passel; Jan 28th, 2021 at 06:32 PM.
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

  8. #8

    Thread Starter
    Member
    Join Date
    Dec 2011
    Location
    Columbus, Ohio
    Posts
    47

    Re: Programming an editable graphic in VB Forms Application

    Sorry for the long delay. Covid, world upside down, blah, blah, blah...

    Thanks to everyone that replied. Very much appreciated.

    Passel - Wow! I tried your code example. I owe you a beer or something for that. I used the resources others pointed me to and your code sample and was able to get this to work as needed. It was amazing how you coded to look exactly like my little drawing. Many thanks.

    Just curious - I am assuming I could just as easily code an ASP.net webpage with the same code. Anyone see a reason why not? Thinking about maybe using it for reporting the coordinates I stored from the Application and applying to web reporting of results.

    Again. Many thanks for the assist to all.

  9. #9
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Programming an editable graphic in VB Forms Application

    Covid??? What's that?
    My usual boring signature: Nothing

  10. #10

    Thread Starter
    Member
    Join Date
    Dec 2011
    Location
    Columbus, Ohio
    Posts
    47

    Re: Programming an editable graphic in VB Forms Application

    Laughing (and crying)

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

    Re: Programming an editable graphic in VB Forms Application

    Quote Originally Posted by DMoody007 View Post
    I am assuming I could just as easily code an ASP.net webpage with the same code. Anyone see a reason why not?
    The reason is that rendering of web pages is completely different Windows Forms. You can use similar principles to determine what the code has to do but the code itself will be quite different.

Tags for this Thread

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