Back in January 2009 I created a Silverlight 2 program that utilized ellipse and line elements.
Since Silverlight 3 is just around the corner, I thought I'd post a demo of this program. Hopefully this will be my last post under Silverlight 2!
As you can see, the program creates various balls positioned nicely in a circle; connected by lines. Each ball has a text and color property you can define, with a click event to go along with it.
Creating the actual objects were the easy part of the project, however most of the work went into the math involved in placing each ellipse and line in the correct spot. Below is example code to make this happen. The ParentBall and ChildBall objects are separate XAML files you can find in the source.
1 Imports System.Windows.Visibility
2 Imports System.Collections.ObjectModel
3
4 Partial Public Class Page
5 Inherits UserControl
6
7 Private m_OverallRadius As Integer = 175 'Overall radius of entire wheel.
8 Private m_CircleDiameter As Integer = 80 'Diameter of each red or green circle.
9 Private m_CircleRadius As Integer = m_CircleDiameter / 2 'Radius of each red or green circle.
10 Private m_Offset As Integer = 500 / 2 - m_CircleRadius 'Offset of wheel from center.
11
12 Public Sub New()
13 InitializeComponent()
14 End Sub
15
16 Private Sub Page_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
17
18 AddParentBalls()
19 AddHandler App.Current.Host.Content.Resized, AddressOf Browser_Resize
20
21 End Sub
22
23 #Region "PARENT BALL RELATED"
24
25 Private Sub AddParentBalls()
26
27 Dim myParents As Collection(Of ParentData) = GetDummyData()
28
29 Dim x As Double = m_OverallRadius
30 Dim y As Double = 0
31 Dim theta As Double = Math.PI / (myParents.Count)
32 Dim I As Integer = 0
33
34 'add the center point
35 AddParentBall(m_Offset, m_Offset, New ParentData(0, "Center Ball", Colors.Black))
36
37 For Each p In myParents
38
39 x = (m_OverallRadius * (Math.Cos((I) * theta)))
40 y = (m_OverallRadius * (Math.Sin((I) * theta)))
41 x += m_Offset
42 y += m_Offset
43
44 AddParentBall(x, y, p)
45
46 Dim x1 As Double, x2 As Double, y1 As Double, y2 As Double
47
48 x1 = m_Offset + m_CircleRadius
49 y1 = m_Offset + m_CircleRadius
50 x2 = x + m_CircleRadius
51 y2 = y + m_CircleRadius
52 AddLine(x1, y1, x2, y2)
53
54 I += 1
55
56 System.Math.Max(System.Threading.Interlocked.Increment(I), I - 1)
57
58 Next p
59
60 End Sub
61
62 Private Sub AddParentBall(ByVal x As Double, ByVal y As Double, ByVal _Parent As ParentData, Optional ByVal IsChild As Boolean = False)
63
64 Dim myBall As New ParentBall(_Parent.ID, _Parent.Name)
65 myBall.Color = _Parent.Color
66
67 With myBall
68 .SetValue(Canvas.LeftProperty, x)
69 .SetValue(Canvas.TopProperty, y)
70 .SetValue(Canvas.ZIndexProperty, 1)
71 End With
72
73 If IsChild = False Then
74 AddHandler myBall.MouseLeftButtonDown, AddressOf ParentBall_MouseLeftButtonDown
75 ParentCanvas.Children.Insert(ParentCanvas.Children.Count, myBall)
76 Else
77 AddHandler myBall.MouseLeftButtonDown, AddressOf ChildBall_MouseLeftButtonDown
78 ChildCanvas.Children.Insert(ChildCanvas.Children.Count, myBall)
79 End If
80
81 End Sub
82
83 Private Sub ParentBall_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
84
85 If Not TypeOf (sender) Is ParentBall Then Exit Sub
86 CreateChildBalls(sender)
87
88 End Sub
89
90 #End Region
91
92 #Region "CHILD BALL RELATED"
93
94 Private Sub CreateChildBalls(ByVal _ParentBall As ParentBall)
95
96 'add the center point
97 Try
98 AddParentBall(m_Offset, m_Offset, New ParentData(0, "Click Me", _ParentBall.Color), True)
99 Catch ex As Exception
100 Exit Sub
101 End Try
102
103 Dim x As Double = m_OverallRadius
104 Dim y As Double = 0
105 Dim theta As Double = Math.PI / (10)
106 Dim I As Integer = 0
107
108 For J As Integer = 1 To 10
109
110 x = (m_OverallRadius * (Math.Cos((I) * theta)))
111 y = (m_OverallRadius * (Math.Sin((I) * theta)))
112 x += m_Offset
113 y += m_Offset
114
115 AddChildBall(x, y, "Child " & J, _ParentBall.Color)
116
117 Dim x1 As Double, x2 As Double, y1 As Double, y2 As Double
118
119 x1 = m_Offset + m_CircleRadius
120 y1 = m_Offset + m_CircleRadius
121 x2 = x + m_CircleRadius
122 y2 = y + m_CircleRadius
123 AddLine(x1, y1, x2, y2, True)
124
125 I += 1
126 System.Math.Max(System.Threading.Interlocked.Increment(I), I - 1)
127
128 Next J
129
130 ParentCanvas.Visibility = Collapsed
131 ChildCanvas.Visibility = Visible
132
133 End Sub
134
135 Private Sub AddChildBall(ByVal x As Double, ByVal y As Double, ByVal [Text] As String, ByVal _Color As Color)
136
137 Dim myBall As New ChildBall([Text])
138 myBall.Color = _Color
139
140 With myBall
141 .SetValue(Canvas.LeftProperty, x)
142 .SetValue(Canvas.TopProperty, y)
143 .SetValue(Canvas.ZIndexProperty, 1)
144 End With
145
146 AddHandler myBall.MouseLeftButtonDown, AddressOf ChildBall_MouseLeftButtonDown
147 ChildCanvas.Children.Insert(ChildCanvas.Children.Count, myBall)
148
149 End Sub
150
151 Private Sub ChildBall_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
152
153 If TypeOf (sender) Is ParentBall Then
154
155 ParentCanvas.Visibility = Visible
156 ChildCanvas.Visibility = Collapsed
157 ChildCanvas.Children.Clear()
158
159 End If
160
161 End Sub
162
163 #End Region
164
165 Private Sub AddLine(ByVal x1 As Double, ByVal y1 As Double, ByVal x2 As Double, ByVal y2 As Double, Optional ByVal IsDevice As Boolean = False)
166
167 Dim myLine As New Line
168
169 With myLine
170 .Stroke = New SolidColorBrush(Colors.Black)
171 .StrokeThickness = 2
172 .X1 = x1
173 .Y1 = y1
174 .X2 = x2
175 .Y2 = y2
176 End With
177
178 If IsDevice = False Then
179 ParentCanvas.Children.Insert(ParentCanvas.Children.Count, myLine)
180 Else
181 ChildCanvas.Children.Insert(ChildCanvas.Children.Count, myLine)
182 End If
183
184 End Sub
185
186 Private Function GetDummyData() As Collection(Of ParentData)
187
188 Dim myParents As New Collection(Of ParentData)
189 Dim myParent As ParentData
190
191 Dim colorArray As New Collection(Of Color)
192 With colorArray
193 .Add(Colors.Red)
194 .Add(Colors.Green)
195 .Add(Colors.Magenta)
196 .Add(Colors.Yellow)
197 .Add(Colors.Purple)
198 .Add(Colors.Blue)
199 .Add(Colors.Orange)
200 .Add(Colors.LightGray)
201 End With
202
203 For I As Integer = 1 To colorArray.Count
204 myParent = New ParentData(I, "Ball " & I, colorArray(I - 1))
205 myParents.Add(myParent)
206 Next I
207
208 Return myParents
209
210 End Function
211
212 Public Sub Browser_Resize(ByVal sender As Object, ByVal e As System.EventArgs)
213
214 Dim ScreenWidth As Double = ActualWidth / 2
215 Dim ScreenHeight As Double = ActualHeight / 2
216
217 Container.Width = ActualWidth
218 Container.Height = ActualHeight
219
220 ParentCanvas.SetValue(Canvas.LeftProperty, ScreenWidth - ParentCanvas.Width / 2)
221 ParentCanvas.SetValue(Canvas.TopProperty, ScreenHeight - ParentCanvas.Height / 2)
222 ChildCanvas.SetValue(Canvas.LeftProperty, ScreenWidth - ChildCanvas.Width / 2)
223 ChildCanvas.SetValue(Canvas.TopProperty, ScreenHeight - ChildCanvas.Width / 2)
224
225 End Sub
226
227 End Class
Anyway, I thought this was a fun little project to show an example using lines and ellipses in Silverlight. Have fun!