Click here to Skip to main content
15,886,657 members
Articles / Desktop Programming / WPF

CurionLib Dynamic Data Entry Forms

Rate me:
Please Sign up or sign in to vote.
5.00/5 (20 votes)
11 Aug 2013CPOL16 min read 54.7K   5.5K   44  
Dynamic data forms.

Namespace Controls.Form
	Public Class MakeXmlForm
		Implements IMakeForm
		'<layout>
		'	<linegroup height="x">
		'		<container title="Title" width="x" type="expander,groupbox,border,clear">
		'			<lines width="x">
		'				csvDef
		Private _csv As New MakeCsvForm
		Private _oneStar As New GridLength(1, GridUnitType.Star)
		Private _oneAuto As New GridLength(1, GridUnitType.Auto)
		Private _form As DataForm
		Public Property ButtonMaker As MakeButton Implements IMakeForm.ButtonMaker
		Private _doc As New Xml.XmlDocument
		Private _id As Integer = 1
		Public Property Doc As Xml.XmlDocument
			Get
				Return _doc
			End Get
			Set(value As Xml.XmlDocument)
				If value Is Nothing Then Throw New NullReferenceException("value must be a valid xml document")
				_doc = value
			End Set
		End Property
		Public Property LayoutXML As String
			Get
				Return _doc.OuterXml
			End Get
			Set(value As String)
				_doc.LoadXml(value)
			End Set
		End Property
		Public Function Create(base As DataForm) As Dictionary(Of String, Control) Implements IMakeForm.Create
			Dim root = _doc.DocumentElement
			_csv.Form = base
			_csv.ButtonMaker = ButtonMaker
			_form = base
			Dim bag = base.Container
			bag.Children.Clear()
			bag.RowDefinitions.Clear()
			bag.ColumnDefinitions.Clear()
			Dim list As New Dictionary(Of String, Control)(StringComparer.CurrentCultureIgnoreCase)
			AddColumn(bag, _oneStar)
			bag.Name = "XML" & _id
			_id += 1
			If base.Title IsNot Nothing Then
				Dim r = AddRow(bag, _oneAuto)
				base.Title.VerticalAlignment = VerticalAlignment.Bottom
				Windows.Controls.Grid.SetRow(base.Title, r)
				Windows.Controls.Grid.SetColumn(base.Title, 0)
				bag.Children.Add(base.Title)
				If base.LineSpacing > 0 Then
					AddRow(bag, New GridLength(base.LineSpacing, GridUnitType.Pixel))
				End If
			End If
			For Each child As Xml.XmlNode In root.ChildNodes
				Select Case LCase(child.Name)
					Case "linegroup"
						Dim size = GetSize(child, "height", "A")
						Dim r = AddRow(bag, size)
						Call LineGroup(bag, child, list, r, 0)
					Case "container"
						Dim r = AddRow(bag, _oneAuto)
						Call Me.Container(bag, child, list, r, 0)
					Case "lines"
						Dim r = AddRow(bag, _oneAuto)
						Call Lines(bag, child, list, r, 0)
				End Select
			Next
			base.Container.RowDefinitions.Add(New RowDefinition With {.Height = New GridLength(base.LineSpacing)})
			Return list
		End Function
		Private Sub LineGroup(container As Grid, root As Xml.XmlElement, list As Dictionary(Of String, Control), row As Integer, col As Integer)
			Dim bag As New Grid
			bag.Name = "LineGroup" & _id
			_id += 1
			Grid.SetRow(bag, row)
			Grid.SetColumn(bag, col)
			AddRow(bag, _oneAuto)
			container.Children.Add(bag)
			For Each child As Xml.XmlElement In root.ChildNodes
				Select Case LCase(child.Name)
					Case "container"
						Dim size = GetSize(child, "width", "1*")
						Dim c = AddColumn(bag, size)
						Call Me.Container(bag, child, list, 0, c)
					Case "lines"
						Dim size = GetSize(child, "width", "1*")
						Dim c = AddColumn(bag, size)
						Call Lines(bag, child, list, 0, c)
				End Select
			Next
		End Sub
		Private Sub Container(container As Grid, root As Xml.XmlElement, list As Dictionary(Of String, Control), row As Integer, col As Integer)
			Dim bag As New Grid
			Dim factType = GetAtr(root, "type")
			Select Case LCase(factType)
				Case "expander"
					Dim fact = New ExpanderColumn
					fact.Title = GetAtr(root, "title")
					Dim control = CType(fact.CreateControl(_form), Expander)
					Dim isOpen = (GetAtr(root, "isopen") <> String.Empty)
					control.IsExpanded = isOpen
					control.HorizontalAlignment = HorizontalAlignment.Stretch
					control.Width = Double.NaN
					control.Height = Double.NaN
					control.Name = "Container" & _id
					_id += 1
					Grid.SetRow(control, row)
					Grid.SetColumn(control, col)
					container.Children.Add(control)
					control.Content = bag
				Case "groupbox"
					Dim fact = New GroupBoxColumn
					fact.Title = GetAtr(root, "title")
					Dim control = CType(fact.CreateControl(_form), GroupBox)
					control.HorizontalAlignment = HorizontalAlignment.Stretch
					control.Width = Double.NaN
					control.Height = Double.NaN
					control.Name = "Container" & _id
					_id += 1
					Grid.SetRow(control, row)
					Grid.SetColumn(control, col)
					container.Children.Add(control)
					control.Content = bag
				Case "border"
					Dim fact = New BorderColumn
					Dim control = CType(fact.CreateControl(_form), Border)
					control.HorizontalAlignment = HorizontalAlignment.Stretch
					control.Name = "Container" & _id
					control.Width = Double.NaN
					control.Height = Double.NaN
					_id += 1
					Grid.SetRow(control, row)
					Grid.SetColumn(control, col)
					container.Children.Add(control)
					control.Child = bag
				Case "clear"
					Grid.SetRow(bag, row)
					Grid.SetColumn(bag, col)
					container.Children.Add(bag)
			End Select
			AddColumn(bag, _oneStar)
			bag.HorizontalAlignment = HorizontalAlignment.Stretch
			bag.Name = "ContainerBag" & _id
			_id += 1

			For Each child As Xml.XmlElement In root.ChildNodes
				Select Case LCase(child.Name)
					Case "lines"
						Dim r = AddRow(bag, _oneAuto)
						Call Lines(bag, child, list, r, 0)
				End Select
			Next
		End Sub
		Private Sub Lines(container As Grid, root As Xml.XmlElement, list As Dictionary(Of String, Control), row As Integer, col As Integer)
			Dim bag As New Grid
			bag.Name = "Lines" & _id
			_id += 1
			Grid.SetRow(bag, row)
			Grid.SetColumn(bag, col)
			container.Children.Add(bag)
			Dim lines As New List(Of String)
			lines.AddRange(Split(root.InnerText, vbCrLf))
			_csv.MakeForm(_form, bag, False, lines, list)
		End Sub
		Private Function GetAtr(root As Xml.XmlElement, attributeName As String) As String
			Dim at = root.Attributes(attributeName)
			If at Is Nothing Then Return String.Empty
			Return at.Value
		End Function
		Private Function GetSize(root As Xml.XmlElement, attributeName As String, defaultValue As String) As GridLength
			Dim value = GetAtr(root, attributeName)
			Dim w As Double = 1.0#
			Dim u As GridUnitType = GridUnitType.Pixel
			Dim v As String = Trim("" & value)
			If v = String.Empty Then v = defaultValue
			Select Case LCase(Right(v, 1))
				Case "a"
					u = GridUnitType.Auto
				Case "*"
					u = GridUnitType.Star
					w = Val(Left(v, v.Length - 1))
				Case Else
					u = GridUnitType.Pixel
					w = Val(v)
			End Select
			Return New GridLength(w, u)
		End Function
		Private Function AddColumn(container As Grid, width As GridLength) As Integer
			Dim cd As New ColumnDefinition With {.Width = width}
			container.ColumnDefinitions.Add(cd)
			Return container.ColumnDefinitions.Count - 1
		End Function
		Private Function AddRow(container As Grid, height As GridLength) As Integer
			Dim rd As New RowDefinition With {.Height = height}
			container.RowDefinitions.Add(rd)
			Return container.RowDefinitions.Count - 1
		End Function
	End Class
End Namespace

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
I enjoy my wife, living in the woods, my 7 dogs, and learning new things. I like to play with UI stuff and model based coding.

Comments and Discussions