yongyih
asked on
Need some advice on how to create a program that can draw data model?
Hi all,
I would like to know what should I use to create a program that able to draw data model?
E.g. I can add two listboxes (or something else) in Form call ListA, ListB. Then ListA will list out all the fields from table A and ListB will list out all the fields from table B. I can drag one of the field in ListA links (draw a line) to one of the field in ListB to show the relationship of two tables.
What should I use or start from if I want to write a program like this? Please advice.
regards,
Yong Yih
I would like to know what should I use to create a program that able to draw data model?
E.g. I can add two listboxes (or something else) in Form call ListA, ListB. Then ListA will list out all the fields from table A and ListB will list out all the fields from table B. I can drag one of the field in ListA links (draw a line) to one of the field in ListB to show the relationship of two tables.
What should I use or start from if I want to write a program like this? Please advice.
regards,
Yong Yih
ASKER
Hi TheLearnedOne,
Any type of database will do. I just want to know how to display a data model in my program. Data model including some square boxes link together by few lines.
May be you try to open an Microsoft Access 2000 database, go to Queries, Create query in Design View. Then add two tables for the query. I believe you can see what I am trying to do.
If you want to give me an example, use Microsoft Access 2000 if possible but I know Oralce and MS SQL also.
Thanks for your reply.
regards
Yong Yih
Any type of database will do. I just want to know how to display a data model in my program. Data model including some square boxes link together by few lines.
May be you try to open an Microsoft Access 2000 database, go to Queries, Create query in Design View. Then add two tables for the query. I believe you can see what I am trying to do.
If you want to give me an example, use Microsoft Access 2000 if possible but I know Oralce and MS SQL also.
Thanks for your reply.
regards
Yong Yih
Since SQL Server has Database Diagrams with a design tool, I was wondering why you want to create your own?
Bob
Bob
Try this example out:
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.ICon tainer
'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 Panel1 As System.Windows.Forms.Panel
Friend WithEvents ListBox2 As System.Windows.Forms.ListB ox
Friend WithEvents ListBox1 As System.Windows.Forms.ListB ox
<System.Diagnostics.Debugg erStepThro ugh()> Private Sub InitializeComponent()
Me.Panel1 = New System.Windows.Forms.Panel
Me.ListBox2 = New System.Windows.Forms.ListB ox
Me.ListBox1 = New System.Windows.Forms.ListB ox
Me.Panel1.SuspendLayout()
Me.SuspendLayout()
'
'Panel1
'
Me.Panel1.AllowDrop = True
Me.Panel1.Controls.Add(Me. ListBox2)
Me.Panel1.Controls.Add(Me. ListBox1)
Me.Panel1.Location = New System.Drawing.Point(8, 8)
Me.Panel1.Name = "Panel1"
Me.Panel1.Size = New System.Drawing.Size(336, 112)
Me.Panel1.TabIndex = 2
'
'ListBox2
'
Me.ListBox2.AllowDrop = True
Me.ListBox2.Location = New System.Drawing.Point(224, 0)
Me.ListBox2.Name = "ListBox2"
Me.ListBox2.Size = New System.Drawing.Size(112, 108)
Me.ListBox2.TabIndex = 3
'
'ListBox1
'
Me.ListBox1.AllowDrop = True
Me.ListBox1.Location = New System.Drawing.Point(0, 0)
Me.ListBox1.Name = "ListBox1"
Me.ListBox1.Size = New System.Drawing.Size(112, 108)
Me.ListBox1.TabIndex = 2
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(352, 174)
Me.Controls.Add(Me.Panel1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.Panel1.ResumeLayout(Fal se)
Me.ResumeLayout(False)
End Sub
#End Region
Private Class ListBoxScroll
Inherits NativeWindow
Private Const WM_VSCROLL = &H115
Public Event Scrolled()
Public Sub New(ByVal lb As ListBox)
Me.AssignHandle(lb.Handle)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Messa ge)
If m.Msg = WM_VSCROLL Then
RaiseEvent Scrolled()
End If
MyBase.WndProc(m)
End Sub
End Class
Private startPoint As Point
Private endPoint As Point
Private startIndex As Integer
Private connections As New Hashtable
Private lastIndex As Integer = -1
Private WithEvents lbs1 As ListBoxScroll
Private WithEvents lbs2 As ListBoxScroll
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim i As Integer
Dim str As String
For i = 1 To 10
str = "Item" & i
ListBox1.Items.Add(str)
ListBox2.Items.Add(str)
Next
ListBox2.Height = ListBox1.Height
Panel1.Height = ListBox1.Height
lbs1 = New ListBoxScroll(Me.ListBox1)
lbs2 = New ListBoxScroll(Me.ListBox2)
End Sub
Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.Mouse EventArgs) Handles ListBox1.MouseDown
If e.Button = MouseButtons.Left Then
Dim pt As New Point(e.X, e.Y)
startIndex = ListBox1.IndexFromPoint(pt )
If startIndex >= 0 Then
Dim itemRc As Rectangle = ListBox1.GetItemRectangle( startIndex )
startPoint = ListBox1.PointToScreen(New Point(ListBox1.Width, itemRc.Top + (itemRc.Bottom - itemRc.Top) / 2))
endPoint = startPoint
lastIndex = -1
ListBox1.DoDragDrop(ListBo x1.Items(s tartIndex) .ToString( ), DragDropEffects.Move)
End If
End If
End Sub
Private Sub ListBox1_QueryContinueDrag (ByVal sender As Object, ByVal e As System.Windows.Forms.Query ContinueDr agEventArg s) Handles ListBox1.QueryContinueDrag
If e.Action = DragAction.Cancel Or e.Action = DragAction.Drop Then
Panel1.Refresh()
End If
End Sub
Private Sub Panel1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragE ventArgs) Handles Panel1.DragOver
ControlPaint.DrawReversibl eLine(star tPoint, endPoint, Panel1.BackColor)
endPoint = New Point(e.X, e.Y)
ControlPaint.DrawReversibl eLine(star tPoint, endPoint, Panel1.BackColor)
End Sub
Private Sub Panel1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragE ventArgs) Handles Panel1.DragEnter
ControlPaint.DrawReversibl eLine(star tPoint, endPoint, Panel1.BackColor)
End Sub
Private Sub Panel1_DragLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Panel1.DragLeave
Panel1.Refresh()
End Sub
Private Sub ListBox2_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragE ventArgs) Handles ListBox2.DragEnter
e.Effect = DragDropEffects.Move
Panel1.Invalidate()
Panel1.Refresh()
End Sub
Private Sub ListBox2_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragE ventArgs) Handles ListBox2.DragOver
Dim lbPoint As Point = ListBox2.PointToClient(New Point(e.X, e.Y))
Dim index As Integer = ListBox2.IndexFromPoint(lb Point)
If index >= 0 Then
ListBox2.SelectedIndex = index
Dim itemRc As Rectangle = ListBox2.GetItemRectangle( index)
Dim key As String
If lastIndex <> index Then
If lastIndex <> -1 Then
key = startIndex & "|" & lastIndex
If Not connections.ContainsKey(ke y) Then
ControlPaint.DrawReversibl eLine(star tPoint, endPoint, Panel1.BackColor)
End If
End If
key = startIndex & "|" & index
If Not connections.ContainsKey(ke y) Then
endPoint = ListBox2.PointToScreen(New Point(0, itemRc.Top + (itemRc.Bottom - itemRc.Top) / 2))
ControlPaint.DrawReversibl eLine(star tPoint, endPoint, Panel1.BackColor)
End If
lastIndex = index
End If
End If
End Sub
Private Sub ListBox2_DragLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox2.DragLeave
Panel1.Refresh()
lastIndex = -1
End Sub
Private Sub ListBox2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragE ventArgs) Handles ListBox2.DragDrop
Dim endIndex As Integer = ListBox2.IndexFromPoint(Li stBox2.Poi ntToClient (New Point(e.X, e.Y)))
If endIndex >= 0 Then
connections.Add(startIndex & "|" & endIndex, Nothing)
End If
Panel1.Refresh()
End Sub
Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.Paint EventArgs) Handles Panel1.Paint
Dim de As DictionaryEntry
Dim indices() As String
For Each de In connections
indices = Split(de.Key, "|")
Dim startRC As Rectangle = ListBox1.GetItemRectangle( indices(0) )
Dim endRC As Rectangle = ListBox2.GetItemRectangle( indices(1) )
Dim List1RC As Rectangle = New Rectangle(New Point(0, 0), ListBox1.Size)
Dim List2RC As Rectangle = New Rectangle(New Point(0, 0), ListBox2.Size)
If List1RC.IntersectsWith(sta rtRC) AndAlso List2RC.IntersectsWith(end RC) Then
Dim startPoint As Point = Panel1.PointToClient(ListB ox1.PointT oScreen(Ne w Point(ListBox1.Width, startRC.Top + (startRC.Bottom - startRC.Top) / 2)))
Dim endPoint As Point = Panel1.PointToClient(ListB ox2.PointT oScreen(Ne w Point(0, endRC.Top + (endRC.Bottom - endRC.Top) / 2)))
e.Graphics.DrawLine(Pens.B lack, startPoint, endPoint)
End If
Next
End Sub
Private Sub lbs1_Scrolled() Handles lbs1.Scrolled
Panel1.Refresh()
End Sub
Private Sub lbs2_Scrolled() Handles lbs2.Scrolled
Panel1.Refresh()
End Sub
End Class
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.ICon
'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 Panel1 As System.Windows.Forms.Panel
Friend WithEvents ListBox2 As System.Windows.Forms.ListB
Friend WithEvents ListBox1 As System.Windows.Forms.ListB
<System.Diagnostics.Debugg
Me.Panel1 = New System.Windows.Forms.Panel
Me.ListBox2 = New System.Windows.Forms.ListB
Me.ListBox1 = New System.Windows.Forms.ListB
Me.Panel1.SuspendLayout()
Me.SuspendLayout()
'
'Panel1
'
Me.Panel1.AllowDrop = True
Me.Panel1.Controls.Add(Me.
Me.Panel1.Controls.Add(Me.
Me.Panel1.Location = New System.Drawing.Point(8, 8)
Me.Panel1.Name = "Panel1"
Me.Panel1.Size = New System.Drawing.Size(336, 112)
Me.Panel1.TabIndex = 2
'
'ListBox2
'
Me.ListBox2.AllowDrop = True
Me.ListBox2.Location = New System.Drawing.Point(224, 0)
Me.ListBox2.Name = "ListBox2"
Me.ListBox2.Size = New System.Drawing.Size(112, 108)
Me.ListBox2.TabIndex = 3
'
'ListBox1
'
Me.ListBox1.AllowDrop = True
Me.ListBox1.Location = New System.Drawing.Point(0, 0)
Me.ListBox1.Name = "ListBox1"
Me.ListBox1.Size = New System.Drawing.Size(112, 108)
Me.ListBox1.TabIndex = 2
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(352, 174)
Me.Controls.Add(Me.Panel1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.Panel1.ResumeLayout(Fal
Me.ResumeLayout(False)
End Sub
#End Region
Private Class ListBoxScroll
Inherits NativeWindow
Private Const WM_VSCROLL = &H115
Public Event Scrolled()
Public Sub New(ByVal lb As ListBox)
Me.AssignHandle(lb.Handle)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Messa
If m.Msg = WM_VSCROLL Then
RaiseEvent Scrolled()
End If
MyBase.WndProc(m)
End Sub
End Class
Private startPoint As Point
Private endPoint As Point
Private startIndex As Integer
Private connections As New Hashtable
Private lastIndex As Integer = -1
Private WithEvents lbs1 As ListBoxScroll
Private WithEvents lbs2 As ListBoxScroll
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim i As Integer
Dim str As String
For i = 1 To 10
str = "Item" & i
ListBox1.Items.Add(str)
ListBox2.Items.Add(str)
Next
ListBox2.Height = ListBox1.Height
Panel1.Height = ListBox1.Height
lbs1 = New ListBoxScroll(Me.ListBox1)
lbs2 = New ListBoxScroll(Me.ListBox2)
End Sub
Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.Mouse
If e.Button = MouseButtons.Left Then
Dim pt As New Point(e.X, e.Y)
startIndex = ListBox1.IndexFromPoint(pt
If startIndex >= 0 Then
Dim itemRc As Rectangle = ListBox1.GetItemRectangle(
startPoint = ListBox1.PointToScreen(New
endPoint = startPoint
lastIndex = -1
ListBox1.DoDragDrop(ListBo
End If
End If
End Sub
Private Sub ListBox1_QueryContinueDrag
If e.Action = DragAction.Cancel Or e.Action = DragAction.Drop Then
Panel1.Refresh()
End If
End Sub
Private Sub Panel1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragE
ControlPaint.DrawReversibl
endPoint = New Point(e.X, e.Y)
ControlPaint.DrawReversibl
End Sub
Private Sub Panel1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragE
ControlPaint.DrawReversibl
End Sub
Private Sub Panel1_DragLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Panel1.DragLeave
Panel1.Refresh()
End Sub
Private Sub ListBox2_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragE
e.Effect = DragDropEffects.Move
Panel1.Invalidate()
Panel1.Refresh()
End Sub
Private Sub ListBox2_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragE
Dim lbPoint As Point = ListBox2.PointToClient(New
Dim index As Integer = ListBox2.IndexFromPoint(lb
If index >= 0 Then
ListBox2.SelectedIndex = index
Dim itemRc As Rectangle = ListBox2.GetItemRectangle(
Dim key As String
If lastIndex <> index Then
If lastIndex <> -1 Then
key = startIndex & "|" & lastIndex
If Not connections.ContainsKey(ke
ControlPaint.DrawReversibl
End If
End If
key = startIndex & "|" & index
If Not connections.ContainsKey(ke
endPoint = ListBox2.PointToScreen(New
ControlPaint.DrawReversibl
End If
lastIndex = index
End If
End If
End Sub
Private Sub ListBox2_DragLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox2.DragLeave
Panel1.Refresh()
lastIndex = -1
End Sub
Private Sub ListBox2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragE
Dim endIndex As Integer = ListBox2.IndexFromPoint(Li
If endIndex >= 0 Then
connections.Add(startIndex
End If
Panel1.Refresh()
End Sub
Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.Paint
Dim de As DictionaryEntry
Dim indices() As String
For Each de In connections
indices = Split(de.Key, "|")
Dim startRC As Rectangle = ListBox1.GetItemRectangle(
Dim endRC As Rectangle = ListBox2.GetItemRectangle(
Dim List1RC As Rectangle = New Rectangle(New Point(0, 0), ListBox1.Size)
Dim List2RC As Rectangle = New Rectangle(New Point(0, 0), ListBox2.Size)
If List1RC.IntersectsWith(sta
Dim startPoint As Point = Panel1.PointToClient(ListB
Dim endPoint As Point = Panel1.PointToClient(ListB
e.Graphics.DrawLine(Pens.B
End If
Next
End Sub
Private Sub lbs1_Scrolled() Handles lbs1.Scrolled
Panel1.Refresh()
End Sub
Private Sub lbs2_Scrolled() Handles lbs2.Scrolled
Panel1.Refresh()
End Sub
End Class
ASKER
Hi Idle_Mind ,
Thanks. Basically that is what I want. I have two more questions here.
1. Is it possible to click on any line to select it, then press DELETE button to delete it.
2. I have to create the listbox and panel during run time to draw the diagram. Number of listbox is unlimited based on users need. Is it possible to do that? Since VB.NET is Object Oriented, I guess it should be possible.
What do you think?
Thanks.
regards,
Yong Yih
Thanks. Basically that is what I want. I have two more questions here.
1. Is it possible to click on any line to select it, then press DELETE button to delete it.
2. I have to create the listbox and panel during run time to draw the diagram. Number of listbox is unlimited based on users need. Is it possible to do that? Since VB.NET is Object Oriented, I guess it should be possible.
What do you think?
Thanks.
regards,
Yong Yih
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
2. I have to create the listbox and panel during run time to draw the diagram. Number of listbox is unlimited based on users need. Is it possible to do that? Since VB.NET is Object Oriented, I guess it should be possible.
I recommend you take the code I have given you and create a UserControl from it. Then you can create as many instances of it as you want.
You will need to provide a way to populate the ListBoxes with the items to connect and a way to retrieve a list of the "relations" the user has made.
This I will leave as an exercise for you to complete as I believe you need to "sweat" over this code a bit. A lot can be learned from trying to make something work...
What you do think Bob...is this question sufficiently answered?....
;)
~IM
I recommend you take the code I have given you and create a UserControl from it. Then you can create as many instances of it as you want.
You will need to provide a way to populate the ListBoxes with the items to connect and a way to retrieve a list of the "relations" the user has made.
This I will leave as an exercise for you to complete as I believe you need to "sweat" over this code a bit. A lot can be learned from trying to make something work...
What you do think Bob...is this question sufficiently answered?....
;)
~IM
ASKER
HI Idle_Mind,
Thank you very much for your codes. You really help me a lot and I believe I can learn a lot from your codes. Haha.. I really save a lot of time and I know where should I start now.
Yes. You gave me more than my expectation. Haha.. As a reward, I will give you 200 points.
regards,
Yong Yih
Thank you very much for your codes. You really help me a lot and I believe I can learn a lot from your codes. Haha.. I really save a lot of time and I know where should I start now.
Yes. You gave me more than my expectation. Haha.. As a reward, I will give you 200 points.
regards,
Yong Yih
Bob