[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Saving Form Controls that are dynamically created in a user preferences file

Posted on 2004-11-12
6
Medium Priority
?
327 Views
Last Modified: 2010-04-24
I have Several Objects that are created dynamically on a form, mainly pictureboxes. I need to be able to save their locations, image properties and text attributes so that on next load those settings can be restored automatically or by loading a preferences file. I was looking into serialization and not sure if this is relevant or not, any suggestions?

Thanks
0
Comment
Question by:draketheon
  • 2
  • 2
  • 2
6 Comments
 
LVL 24

Expert Comment

by:Jeff Certain
ID: 12567703
Are you creating a desktop application or a web application?

The following comments assume that this is a web-based application, due to your "next load" comment.

There are a couple of ways to do this. As I'm sure you've discovered, dynamically created objects do not persist between postbacks. Probably the easiest way to do this is to store the data in a session variable and restore them on page load.

If you need to retrieve information that is changed (i.e. the text in a textbox control), use the request.page.form object to get the data. The easiest way to see what data is available is to enable the trace for the page. Generally, only information that can be changed by the user is included, so you'll have to store your other data (i.e. programatically set locations)  yourself.

This is a simple work-around for objects that you only need some information from.

Jeff
0
 
LVL 1

Author Comment

by:draketheon
ID: 12567808
Actually this would be a desktop app. I also do alot of webdeving so next load kind of sliped out, sorry for the confusion. Actually when the app is run again.
0
 
LVL 24

Expert Comment

by:Jeff Certain
ID: 12567993
Haven't done much desktop dev since .Net came out. I'd guess your best approach would be to load from a preferences file.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 1000 total points
ID: 12568329
Serialization is definitely relevant here.

You can create a class to hold the information about the size, location, filename, etc. of each PictureBox you create.  Then, for each PictureBox you create, also create an instance of this class to store the information about that picturebox.  Store the instances of your info class in an ArrayList.  Then use serialization to store the instances to a file.

Here is a demonstration app I wrote that does exactly what I have described above.  The application consists of one form and one class, both listed below.  Drag rectangles on the form to create a new signs.  Double click the signs to edit the text in them (Press ESC to exit edit mode).  Press the "Connect" button to connect two signs together (Red boxes will appear when you hover over a box to show connection points).  Resize, move and connect the boxes to hearts content.  When you have several signs created, you can serialize them using the "Save Layout" button.  Finally, close the app and reopen it. Now use the "Load Layout" button to recreate the dynamic signs you just made.

The code is a little long but the app is fun to play with.

Hope it helps,

Idle_Mind

' -------------------------------------------------------------------------------------------
' Form1
' -------------------------------------------------------------------------------------------
Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents PictureBox1 As System.Windows.Forms.PictureBox
    Friend WithEvents FontDialog1 As System.Windows.Forms.FontDialog
    Friend WithEvents ColorDialog1 As System.Windows.Forms.ColorDialog
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents Button2 As System.Windows.Forms.Button
    Friend WithEvents OpenFileDialog1 As System.Windows.Forms.OpenFileDialog
    Friend WithEvents SaveFileDialog1 As System.Windows.Forms.SaveFileDialog
    Friend WithEvents Button3 As System.Windows.Forms.Button
    Friend WithEvents Button4 As System.Windows.Forms.Button
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.PictureBox1 = New System.Windows.Forms.PictureBox
        Me.FontDialog1 = New System.Windows.Forms.FontDialog
        Me.ColorDialog1 = New System.Windows.Forms.ColorDialog
        Me.Button1 = New System.Windows.Forms.Button
        Me.Button2 = New System.Windows.Forms.Button
        Me.OpenFileDialog1 = New System.Windows.Forms.OpenFileDialog
        Me.SaveFileDialog1 = New System.Windows.Forms.SaveFileDialog
        Me.Button3 = New System.Windows.Forms.Button
        Me.Button4 = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'PictureBox1
        '
        Me.PictureBox1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
                    Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.PictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.PictureBox1.Location = New System.Drawing.Point(8, 40)
        Me.PictureBox1.Name = "PictureBox1"
        Me.PictureBox1.Size = New System.Drawing.Size(616, 336)
        Me.PictureBox1.TabIndex = 0
        Me.PictureBox1.TabStop = False
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(8, 8)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(112, 24)
        Me.Button1.TabIndex = 1
        Me.Button1.Text = "Load Layout"
        '
        'Button2
        '
        Me.Button2.Location = New System.Drawing.Point(128, 8)
        Me.Button2.Name = "Button2"
        Me.Button2.Size = New System.Drawing.Size(112, 24)
        Me.Button2.TabIndex = 2
        Me.Button2.Text = "Save Layout"
        '
        'Button3
        '
        Me.Button3.Location = New System.Drawing.Point(248, 8)
        Me.Button3.Name = "Button3"
        Me.Button3.Size = New System.Drawing.Size(112, 24)
        Me.Button3.TabIndex = 3
        Me.Button3.Text = "Delete Sign"
        '
        'Button4
        '
        Me.Button4.Location = New System.Drawing.Point(368, 8)
        Me.Button4.Name = "Button4"
        Me.Button4.Size = New System.Drawing.Size(112, 24)
        Me.Button4.TabIndex = 5
        Me.Button4.Text = "Connect"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(8, 19)
        Me.ClientSize = New System.Drawing.Size(632, 382)
        Me.Controls.Add(Me.Button4)
        Me.Controls.Add(Me.Button3)
        Me.Controls.Add(Me.Button2)
        Me.Controls.Add(Me.Button1)
        Me.Controls.Add(Me.PictureBox1)
        Me.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Name = "Form1"
        Me.Text = "RubberBanding Connectable Boxes in a PictureBox"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private Enum Action
        None = 0
        Creating = 1
        Sizing = 2
        Moving = 3
        Deleting = 4
        Connecting = 5
    End Enum

    Private startX As Integer
    Private startY As Integer
    Private lastX As Integer
    Private lastY As Integer
    Private firstBoxDrawn As Boolean = False
    Private Signs As New ArrayList
    Private curAction As Action = Action.None
    Private s As Sign
    Private se As Sign.SignEdge
    Private curSign As Sign
    Private selSign As Sign
    Private firstPoint As Boolean
    Private sourceSign As Sign
    Private sourceEdge As Sign.SignEdge
    Private targetSign As Sign
    Private targetEdge As Sign.SignEdge

    Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        If e.Button = MouseButtons.Left Then
            If curAction = Action.None Then
                Dim p As Point = PictureBox1.PointToScreen(New Point(e.X, e.Y))
                startX = p.X
                startY = p.Y
                If curSign Is Nothing Then
                    If Not (selSign Is Nothing) Then
                        selSign.showHandles = False
                        selSign = Nothing
                        PictureBox1.Refresh()
                    End If
                ElseIf Not (curSign Is selSign) Then
                    If Not (selSign Is Nothing) Then
                        selSign.showHandles = False
                    End If
                    selSign = curSign
                    selSign.showHandles = True
                    PictureBox1.Refresh()
                End If
            ElseIf curAction = Action.Deleting Then
                If Not (curSign Is Nothing) Then
                    Signs.Remove(curSign)
                    PictureBox1.Refresh()
                End If
                Button3.Enabled = True
                curAction = Action.None
            ElseIf curAction = Action.Connecting Then
                If Not (se = Sign.SignEdge.None) Then
                    If Not firstPoint Then
                        sourceSign = curSign
                        sourceEdge = se
                        firstPoint = True
                    ElseIf Not (curSign Is sourceSign) Then
                        targetSign = curSign
                        targetEdge = se
                        sourceSign.ConnectTo(sourceEdge, targetSign, targetEdge)
                        curAction = Action.None
                        Button4.Enabled = True
                        PictureBox1.Refresh()
                    End If
                End If
            End If
        End If
    End Sub

    Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        Dim p As Point
        If e.Button = MouseButtons.Left Then
            Select Case curAction
                Case Action.None
                    Cursor.Clip = sender.RectangleToScreen(New Rectangle(0, 0, sender.Width, sender.Height))
                    If Not (s Is Nothing) Then
                        If se = Sign.SignEdge.None Then
                            curAction = Action.Moving
                            s.dragSign(sender, e.X, e.Y)
                        Else
                            curAction = Action.Sizing
                            s.dragEdge(sender, se, e.X, e.Y)
                        End If
                    Else
                        curAction = Action.Creating
                        firstBoxDrawn = False
                        createSign(sender, e)
                    End If

                Case Action.Creating
                    createSign(sender, e)

            End Select
        ElseIf curAction = Action.None Or _
                curAction = Action.Deleting Or _
                curAction = Action.Connecting Then
            HighlightSign(sender, e)
            If curAction = Action.Connecting And firstPoint Then
                PictureBox1.Refresh()
                Dim g As Graphics = PictureBox1.CreateGraphics
                g.DrawLine(Pens.Black, sourceSign.getHandleCoord(sourceEdge), New Point(e.X, e.Y))
                g.Dispose()
            End If
        End If
    End Sub

    Private Sub HighlightSign(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        overSign(sender, e)
        If s Is Nothing Then
            If Not (curSign Is Nothing) Then
                curSign.Highlighted = False
                curSign.ConnectionCandidate = False
                curSign = Nothing
                sender.Refresh()
            End If
        Else
            If curSign Is Nothing Then
                curSign = s
                If curAction = Action.Connecting Then
                    curSign.ConnectionCandidate = True
                Else
                    curSign.Highlighted = True
                End If
                sender.Refresh()
            ElseIf Not (curSign Is s) Then
                curSign.Highlighted = False
                curSign.ConnectionCandidate = False
                curSign = s
                If curAction = Action.Connecting Then
                    curSign.ConnectionCandidate = True
                Else
                    curSign.Highlighted = True
                End If
                sender.Refresh()
            End If
        End If
    End Sub

    Private Sub overSign(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        s = Nothing
        se = Sign.SignEdge.None

        For Each s In Signs
            If s.signAction = Sign.Action.None Then
                se = s.isOverEdge(e.X, e.Y)
                If se <> Sign.SignEdge.None Then
                    If curAction = Action.Connecting Then
                        If s Is sourceSign Then
                            s = Nothing
                            se = Sign.SignEdge.None
                            sender.Cursor.Current = Cursors.Default
                        Else
                            sender.Cursor.Current = Cursors.Cross
                        End If
                        Exit Sub
                    ElseIf curAction = Action.Deleting Then
                        sender.Cursor.Current = Cursors.Cross
                        Exit Sub
                    ElseIf curAction = Action.None Then
                        If s.showHandles Then
                            Select Case se
                                Case Sign.SignEdge.North, Sign.SignEdge.South
                                    sender.Cursor.Current = Cursors.SizeNS

                                Case Sign.SignEdge.NorthEast, Sign.SignEdge.SouthWest
                                    sender.Cursor.Current = Cursors.SizeNESW

                                Case Sign.SignEdge.East, Sign.SignEdge.West
                                    sender.Cursor.Current = Cursors.SizeWE

                                Case Sign.SignEdge.SouthEast, Sign.SignEdge.NorthWest
                                    sender.Cursor.Current = Cursors.SizeNWSE

                            End Select
                            Exit Sub
                        Else
                            se = Sign.SignEdge.None
                        End If
                    End If
                End If
            End If
        Next

        For Each s In Signs
            If s.signAction = Sign.Action.None And s.isOverSign(e.X, e.Y) Then
                If (Not (selSign Is Nothing)) AndAlso (Not (s Is selSign)) Then
                    If selSign.isOverSign(e.X, e.Y) Then
                        s = selSign
                    End If
                End If
                If curAction = Action.Deleting Then
                    sender.Cursor.Current = Cursors.Cross
                ElseIf curAction = Action.Connecting Then
                    If s Is sourceSign Then
                        s = Nothing
                        se = Sign.SignEdge.None
                        sender.Cursor.Current = Cursors.Default
                    Else
                        sender.Cursor.Current = Cursors.Cross
                    End If
                ElseIf curAction = Action.None Then
                    sender.Cursor.Current = Cursors.SizeAll
                End If
                Exit Sub
            End If
        Next

        s = Nothing
        se = Sign.SignEdge.None
        sender.Cursor.Current = Cursors.Default
    End Sub

    Private Sub createSign(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        Dim p As Point = sender.PointToScreen(New Point(e.X, e.Y))
        If Not firstBoxDrawn Then
            firstBoxDrawn = True
            ControlPaint.DrawReversibleFrame(New Rectangle(startX, startY, p.X - startX, p.Y - startY), Color.Black, FrameStyle.Dashed)
        Else
            ControlPaint.DrawReversibleFrame(New Rectangle(startX, startY, lastX - startX, lastY - startY), Color.Black, FrameStyle.Dashed)
            ControlPaint.DrawReversibleFrame(New Rectangle(startX, startY, p.X - startX, p.Y - startY), Color.Black, FrameStyle.Dashed)
        End If
        lastX = p.X
        lastY = p.Y
    End Sub

    Private Sub PictureBox1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
        If e.Button = MouseButtons.Left Then
            If Not (curAction = Action.Connecting) Then
                Cursor.Clip = New Rectangle(0, 0, Screen.GetBounds(New Point(0, 0)).Width, Screen.GetBounds(New Point(0, 0)).Height)
                If curAction = Action.Creating Then
                    If firstBoxDrawn Then
                        Dim r As Rectangle = New Rectangle(Math.Min(startX, lastX), Math.Min(startY, lastY), Math.Abs(lastX - startX), Math.Abs(lastY - startY))
                        ControlPaint.DrawReversibleFrame(r, Color.Black, FrameStyle.Dashed)
                        r = PictureBox1.RectangleToClient(r)
                        Dim s As New Sign(r)
                        s.Text = "New Sign" & vbCrLf & vbCrLf & Now().ToString
                        s.showHandles = True
                        s.Highlighted = True
                        Signs.Add(s)
                        selSign = s
                        sender.Refresh()
                    End If
                End If
                curAction = Action.None
                PictureBox1.Cursor.Show()
            End If
        End If
    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        Dim s As Sign
        For Each s In Signs
            If Not (s Is selSign) Then
                s.Paint(sender, e)
            End If
        Next
        If Not (selSign Is Nothing) Then
            selSign.Paint(sender, e)
        End If
    End Sub

    Private Sub PictureBox1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.DoubleClick
        Dim s As Sign
        Dim p As Point
        For Each s In Signs
            p = PictureBox1.PointToClient(Cursor.Position)
            If s.isOverSign(p.X, p.Y) Then
                If Not (selSign Is Nothing) Then
                    If selSign.isOverSign(p.X, p.Y) Then
                        s = selSign
                    End If
                End If

                Dim tb As New TextBox
                tb.BorderStyle = BorderStyle.None
                tb.BackColor = PictureBox1.BackColor
                tb.ForeColor = s.TextColor
                tb.Multiline = True
                Dim sLoc As Point = Me.PointToClient(PictureBox1.PointToScreen(s.signLocation))
                Dim sSize As Size = s.signSize
                sLoc.X = sLoc.X + s.HandleWidth + 2
                sLoc.Y = sLoc.Y + s.HandleWidth
                sSize.Width = sSize.Width - (2 * s.HandleWidth)
                sSize.Height = sSize.Height - (2 * s.HandleWidth)
                tb.Location = sLoc
                tb.Size = sSize
                tb.Text = s.Text
                If s.TextFont Is Nothing Then
                    tb.Font = PictureBox1.Font
                Else
                    tb.Font = s.TextFont
                End If
                tb.Tag = s

                AddHandler tb.KeyPress, AddressOf Me.tb_KeyPress
                AddHandler tb.KeyDown, AddressOf Me.tb_KeyDown
                Me.Controls.Add(tb)
                tb.Visible = True
                tb.BringToFront()
                tb.Focus()
                tb.SelectionStart = tb.Text.Length
                s.signAction = Sign.Action.Editing
                PictureBox1.Refresh()
                Exit Sub
            End If
        Next
    End Sub

    Private Sub tb_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
        If Asc(e.KeyChar) = 27 Then ' Escape
            sender.tag.text = sender.text
            sender.tag.signaction = Sign.Action.None
            Me.Controls.Remove(sender)
            PictureBox1.Refresh()
        End If
    End Sub

    Private Sub tb_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
        If e.KeyCode = Keys.F9 Then
            If FontDialog1.ShowDialog = DialogResult.OK Then
                sender.Tag.TextFont = FontDialog1.Font
                sender.Font = FontDialog1.Font
            End If
        ElseIf e.KeyCode = Keys.F10 Then
            If ColorDialog1.ShowDialog = DialogResult.OK Then
                sender.Tag.TextColor = ColorDialog1.Color
                sender.ForeColor = ColorDialog1.Color
            End If
        End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        OpenFileDialog1.Title = "Open a Previously Saved Layout"
        OpenFileDialog1.Filter = "Sign Layout Files (*.sly)|*.sly|All files (*.*)|*.*"
        If OpenFileDialog1.ShowDialog = DialogResult.OK Then
            Dim fs As New FileStream(OpenFileDialog1.FileName, FileMode.OpenOrCreate)
            Dim formatter As New BinaryFormatter
            Try
                Signs = DirectCast(formatter.Deserialize(fs), ArrayList)
                PictureBox1.Refresh()
            Catch x As SerializationException
                MsgBox("Failed to Deserialize. Reason: " & x.Message)
                Throw
            Finally
                fs.Close()
                MsgBox(OpenFileDialog1.FileName, MsgBoxStyle.Information, "Sign Layout Loaded")
            End Try
        End If
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        SaveFileDialog1.Title = "Save Sign Layout to a File"
        SaveFileDialog1.Filter = "Sign Layout Files (*.sly)|*.sly|All files (*.*)|*.*"
        If SaveFileDialog1.ShowDialog = DialogResult.OK Then
            Dim fs As New FileStream(SaveFileDialog1.FileName, FileMode.Create)
            Dim formatter As New BinaryFormatter
            Try
                formatter.Serialize(fs, Signs)
            Catch x As SerializationException
                MsgBox("Failed to serialize. Reason: " & x.Message)
                Throw
            Finally
                fs.Close()
                MsgBox(SaveFileDialog1.FileName, MsgBoxStyle.Information, "Sign Layout Saved")
            End Try
        End If
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Button3.Enabled = False
        curAction = Action.Deleting
    End Sub

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        Button4.Enabled = False
        If Not (selSign Is Nothing) Then
            selSign.showHandles = False
            selSign = Nothing
            PictureBox1.Refresh()
        End If
        sourceSign = Nothing
        sourceEdge = Sign.SignEdge.None
        targetSign = Nothing
        targetEdge = Sign.SignEdge.None
        firstPoint = False
        curAction = Action.Connecting
    End Sub

End Class

' -------------------------------------------------------------------------------------------
' Class Sign
' -------------------------------------------------------------------------------------------
<Serializable()> Public Class Sign

    Public Enum SignEdge
        None = 0
        North = 1
        NorthEast = 2
        East = 3
        SouthEast = 4
        South = 5
        SouthWest = 6
        West = 7
        NorthWest = 8
    End Enum

    Public Enum Action
        None = 0
        Resize = 1
        Move = 2
        Editing = 3
    End Enum

    Public Text As String
    Public TextFont As Font
    Public TextColor As Color = Color.Black
    Private Rect As Rectangle
    Private RectHandles(7) As Rectangle
    Private Connections(7) As ArrayList

    Public ReadOnly Property signSize() As Size
        Get
            Return Rect.Size
        End Get
    End Property

    Public ReadOnly Property signLocation() As Point
        Get
            Return New Point(Rect.X, Rect.Y)
        End Get
    End Property

    Public Property signAction() As Action
        Get
            Return curAction
        End Get
        Set(ByVal Value As Action)
            curAction = Value
        End Set
    End Property

    Public ReadOnly Property getHandleCoord(ByVal edge As SignEdge) As Point
        Get
            Dim p As Point = New Point(Rect.X, Rect.Y)
            If Not (edge = SignEdge.None) Then
                p.X = RectHandles(edge - 1).X + (HandleWidth / 2)
                p.Y = RectHandles(edge - 1).Y + (HandleWidth / 2)
            End If
            Return p
        End Get
    End Property

    <NonSerialized()> Public showHandles As Boolean = False
    <NonSerialized()> Public Highlighted As Boolean = False
    <NonSerialized()> Public ConnectionCandidate As Boolean = False
    <NonSerialized()> Private draggingEdge As SignEdge = SignEdge.None
    <NonSerialized()> Private startX As Integer
    <NonSerialized()> Private startY As Integer
    <NonSerialized()> Private curAction As Action = Action.None
    <NonSerialized()> Public Const HandleWidth As Byte = 8
    <NonSerialized()> Private WithEvents sourcePictureBox As PictureBox = Nothing

    Private Sub New()
    End Sub

    Public Sub New(ByVal r As Rectangle)
        Rect = r
        updateRectHandles()
        Dim i As Integer
        For i = 0 To 7
            Connections(i) = New ArrayList
        Next
    End Sub

    Public Sub Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
        If curAction = Action.Editing Then
            Dim pb As PictureBox = CType(sender, PictureBox)
            Dim sb As New SolidBrush(pb.BackColor)
            e.Graphics.FillRectangle(sb, Rect)
            sb.Dispose()
        End If
        If Highlighted Then
            e.Graphics.DrawRectangle(Pens.Red, Rect)
        Else
            e.Graphics.DrawRectangle(Pens.Black, Rect)
        End If
        If showHandles Then
            e.Graphics.FillRectangles(Brushes.Black, RectHandles)
        End If

        Dim textRect As New RectangleF(Rect.X + HandleWidth, Rect.Y + HandleWidth, Rect.Width - (2 * HandleWidth), Rect.Height - (2 * HandleWidth))
        If textRect.Width > 0 And textRect.Height > 0 Then
            Dim b As New SolidBrush(TextColor)
            e.Graphics.DrawString(Text, _
            IIf(TextFont Is Nothing, sender.font, TextFont), b, textRect)
            b.Dispose()
        End If

        Dim i As Integer
        Dim c As Connection
        Dim sourcePoint As Point
        Dim targetPoint As Point
        For i = 0 To 7
            For Each c In Connections(i)
                sourcePoint = Me.getHandleCoord(i + 1)
                targetPoint = c.ToSign.getHandleCoord(c.ToEdge)
                e.Graphics.DrawLine(Pens.Black, sourcePoint, targetPoint)
            Next
        Next

        If ConnectionCandidate Then
            e.Graphics.FillRectangles(Brushes.Red, RectHandles)
        End If
    End Sub

    Public Function isOverEdge(ByVal x As Integer, ByVal y As Integer) As SignEdge
        Dim i As Integer

        For i = 1 To 8
            If RectHandles(i - 1).Contains(x, y) Then
                Return i
            End If
        Next
        Return SignEdge.None
    End Function

    Public Function isOverSign(ByVal x As Integer, ByVal y As Integer) As Boolean
        Return Rect.Contains(x, y)
    End Function

    Public Sub dragEdge(ByVal pb As PictureBox, ByVal edge As SignEdge, ByVal x As Integer, ByVal y As Integer)
        curAction = Action.Resize
        draggingEdge = edge
        startX = x
        startY = y
        sourcePictureBox = pb
    End Sub

    Public Sub dragSign(ByVal pb As PictureBox, ByVal x As Integer, ByVal y As Integer)
        curAction = Action.Move
        startX = x
        startY = y
        sourcePictureBox = pb
    End Sub

    Private Sub sourcePictureBox_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles sourcePictureBox.MouseMove
        Dim p As Point
        Select Case curAction
            Case Action.Resize
                Select Case draggingEdge
                    Case SignEdge.North
                        Rect.Y = Rect.Y + (e.Y - startY)
                        Rect.Height = Rect.Height - (e.Y - startY)

                    Case SignEdge.NorthEast
                        Rect.Y = Rect.Y + (e.Y - startY)
                        Rect.Height = Rect.Height - (e.Y - startY)
                        Rect.Width = Rect.Width + (e.X - startX)

                    Case SignEdge.East
                        Rect.Width = Rect.Width + (e.X - startX)

                    Case SignEdge.SouthEast
                        Rect.Height = Rect.Height + (e.Y - startY)
                        Rect.Width = Rect.Width + (e.X - startX)

                    Case SignEdge.South
                        Rect.Height = Rect.Height + (e.Y - startY)

                    Case SignEdge.SouthWest
                        Rect.Height = Rect.Height + (e.Y - startY)
                        Rect.X = Rect.X + (e.X - startX)
                        Rect.Width = Rect.Width - (e.X - startX)

                    Case SignEdge.West
                        Rect.X = Rect.X + (e.X - startX)
                        Rect.Width = Rect.Width - (e.X - startX)

                    Case SignEdge.NorthWest
                        Rect.Y = Rect.Y + (e.Y - startY)
                        Rect.Height = Rect.Height - (e.Y - startY)
                        Rect.X = Rect.X + (e.X - startX)
                        Rect.Width = Rect.Width - (e.X - startX)

                End Select
                If Rect.Width < 0 Then
                    Rect.X = Rect.X + Rect.Width
                    Rect.Width = Math.Abs(Rect.Width)
                    Select Case draggingEdge
                        Case SignEdge.NorthEast
                            draggingEdge = SignEdge.NorthWest

                        Case SignEdge.East
                            draggingEdge = SignEdge.West

                        Case SignEdge.SouthEast
                            draggingEdge = SignEdge.SouthWest

                        Case SignEdge.SouthWest
                            draggingEdge = SignEdge.SouthEast

                        Case SignEdge.West
                            draggingEdge = SignEdge.East

                        Case SignEdge.NorthWest
                            draggingEdge = SignEdge.NorthEast

                    End Select
                End If
                If Rect.Height < 0 Then
                    Rect.Y = Rect.Y + Rect.Height
                    Rect.Height = Math.Abs(Rect.Height)
                    Select Case draggingEdge
                        Case SignEdge.North
                            draggingEdge = SignEdge.South

                        Case SignEdge.NorthEast
                            draggingEdge = SignEdge.SouthEast

                        Case SignEdge.SouthEast
                            draggingEdge = SignEdge.NorthEast

                        Case SignEdge.South
                            draggingEdge = SignEdge.North

                        Case SignEdge.SouthWest
                            draggingEdge = SignEdge.NorthWest

                        Case SignEdge.NorthWest
                            draggingEdge = SignEdge.SouthWest
                    End Select
                End If
                updateRectHandles()
                startX = e.X
                startY = e.Y
                sender.Refresh()

            Case Action.Move
                Rect.X = Rect.X + (e.X - startX)
                Rect.Y = Rect.Y + (e.Y - startY)
                updateRectHandles()
                startX = e.X
                startY = e.Y
                sender.Refresh()
        End Select
    End Sub

    Private Sub sourcePictureBox_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles sourcePictureBox.MouseUp
        sourcePictureBox = Nothing
        curAction = Action.None
    End Sub

    Private Sub updateRectHandles()
        Dim halfThreshold As Single = HandleWidth / 2
        RectHandles(0) = New Rectangle(Rect.X + (Rect.Width / 2) - halfThreshold, Rect.Y - halfThreshold, HandleWidth, HandleWidth)
        RectHandles(1) = New Rectangle(Rect.X + Rect.Width - halfThreshold, Rect.Y - halfThreshold, HandleWidth, HandleWidth)
        RectHandles(2) = New Rectangle(Rect.X + Rect.Width - halfThreshold, Rect.Y + (Rect.Height / 2) - halfThreshold, HandleWidth, HandleWidth)
        RectHandles(3) = New Rectangle(Rect.X + Rect.Width - halfThreshold, Rect.Y + Rect.Height - halfThreshold, HandleWidth, HandleWidth)
        RectHandles(4) = New Rectangle(Rect.X + (Rect.Width / 2) - halfThreshold, Rect.Y + Rect.Height - halfThreshold, HandleWidth, HandleWidth)
        RectHandles(5) = New Rectangle(Rect.X - halfThreshold, Rect.Y + Rect.Height - halfThreshold, HandleWidth, HandleWidth)
        RectHandles(6) = New Rectangle(Rect.X - halfThreshold, Rect.Y + (Rect.Height / 2) - halfThreshold, HandleWidth, HandleWidth)
        RectHandles(7) = New Rectangle(Rect.X - halfThreshold, Rect.Y - halfThreshold, HandleWidth, HandleWidth)
    End Sub

    Public Sub ConnectTo(ByVal FromEdge As SignEdge, ByVal ToSign As Sign, ByVal ToEdge As SignEdge)
        If (Not (ToSign Is Nothing)) And (Not (ToSign Is Me)) Then
            If (Not (FromEdge = SignEdge.None)) And (Not (ToEdge = SignEdge.None)) Then
                Dim c As New Connection
                c.ToSign = ToSign
                c.ToEdge = ToEdge
                Connections(FromEdge - 1).Add(c)
            End If
        End If
    End Sub

    <Serializable()> Private Class Connection
        Public ToSign As Sign
        Public ToEdge As SignEdge
    End Class

End Class
0
 
LVL 1

Author Comment

by:draketheon
ID: 12569048
Wow how long did that take you?
Thanks Idle_Mind, I quickly tested it and thats the idea I was looking for. It will take some studying to figure out how I can implement a similar idea into my project
but it will definitely help me understand the idea behind serialization.

Thanks Again.



0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 12570070
This particular demo only took about a day and a half to throw together.  I have written similar applications before though, so I know what goes into them and can churn them out pretty quickly.

Most of the code is related to the creation, moving and resizing of the boxes.  The important things for serialization are making sure to mark your class with the <Serializable()> tag.  Any variables in the class not marked with the <NonSerialized()>  tag will then get serialized.  The ArrayList is nice because it supports serialization.  (The Collection class carried over from VB6 does not.)

The example I presented uses Binary serialization, which looks greek to the typical user if they open up the file, discouraging average "hackers".  This can be a good thing depending on your application.  Implementing XML serialization wouldn't be much different and would allow you (or your users) the ability to edit the serialized file with notepad or a similar text editor.  That can be a bad thing depending on your application...just depends on what your doing I suppose.  =)

In your case, after deserializing the ArrayList, you would simply walk it and create new PictureBoxes based on the data in each class contained within, adding them to the Forms control collection as you go.

Please don't hesitate to ask questions in this thread regarding the code I posted or any serialization questions in general.

~IM
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
this video summaries big data hadoop online training demo (http://onlineitguru.com/big-data-hadoop-online-training-placement.html) , and covers basics in big data hadoop .
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Suggested Courses

868 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question