Click here to Skip to main content
15,885,365 members
Articles / Programming Languages / C# 4.0

Relationship Oriented Programming - The IDE plus More on Agile Project Management

Rate me:
Please Sign up or sign in to vote.
4.98/5 (25 votes)
12 Mar 2012CPOL81 min read 77.5K   1.2K   49  
An Integrated Development Environment (IDE) for the Relationship Oriented Programming Tool.
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Linq;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;

using MyXaml.Core;

using ROPLib;
using ROPLib.Data;
using ROPLib.RendererInterfaces;
using ROPLib.UIEvents;

using Interfaces.UI;

// Some interesting reading regarding "where in " : http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/095745fe-dcf0-4142-b684-b7e4a1ab59f0/

namespace ROPLib.UIRendering
{
	// public enum DataType {Integer, String, Bool, DateTime};

	public class Render : IRender
	{
		public void RenderEntity(EntityProvider dataSet, Mode renderMode)
		{
			new RenderEntity(this, dataSet).Go(renderMode);
		}

		public void RenderEntity(EntityProvider dataSet, Mode renderMode, List<int> pkList)
		{
			RenderEntity renderer = new RenderEntity(this, dataSet);
			renderer.PKList = pkList;
			renderer.Go(renderMode);
		}
	}

	public class RenderEntity : IRenderEntity
	{
		[MyXamlAutoInitialize]
		IGrid grid1 = null;

		protected IRender render;
		protected EntityProvider dataSet;
		protected Mode renderMode;
		protected XElement root;
		protected EventHandlers eventHandlers;

		public List<int> PKList { get; set; }
		public Mode RenderMode { get { return renderMode; } }

		public RenderEntity(IRender render, EntityProvider dataSet)
		{
			this.render = render;
			this.dataSet = dataSet;
			eventHandlers = new EventHandlers(dataSet, render, this);
		}

		public void Go(Mode renderMode)
		{
			this.renderMode = renderMode;
			string entityTypeName = dataSet.GetEntityTypeName();
			XDocument xdoc = new XDocument();
			XNamespace nsswf = "System.Windows.Forms,  System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
			XElement controls;
			xdoc.Add(
				root = new XElement(nsswf + "MyXaml", 
					new XAttribute(XNamespace.Xmlns+"def", "Definition"),
					new XAttribute(XNamespace.Xmlns + "ref", "Reference"),
					new XElement(nsswf + "Form", 
						new XAttribute("Text", entityTypeName),
						new XAttribute("ClientSize", "500, 600"),
						controls = new XElement(nsswf + "Controls"))));

			int x = 10;
			int y = 10;
			int bindingNavigatorOffset = 0;

			switch (renderMode)
			{
				case Mode.Grid:
				{
					RopGrid(nsswf, controls, dataSet.Attributes, ref x, ref y, "Top, Bottom, Left, Right", "grid1");
					break;
				}
				case Mode.Discrete:
				{
					bindingNavigatorOffset = 25;
					RopBindingNavigator(nsswf, controls, ref x, ref y);
					CreateDiscreteControls(nsswf, controls, dataSet.Attributes, ref x, ref y);

					break;
				}
				case Mode.Hybrid:
				{
					RopNewButton(nsswf, controls);
					RopGrid(nsswf, controls, dataSet.Attributes, ref x, ref y, "Top, Left, Right", "grid1");
					CreateDiscreteControls(nsswf, controls, dataSet.Attributes, ref x, ref y);

					break;
				}
			}

			RopSaveButton(nsswf, controls, 10+bindingNavigatorOffset);

			// The part of the UI for associating an entity instance with another instance:
			List<Association> parentEntityTypes = dataSet.GetParentEntityTypes();
			List<Association> childEntityTypes = dataSet.GetChildEntityTypes();

			// Copy, because otherwise the two comboboxes are linked together.
			List<Association> navParentEntityTypes = new List<Association>();
			navParentEntityTypes.AddRange(parentEntityTypes);
			List<Association> navChildEntityTypes = new List<Association>();
			navChildEntityTypes.AddRange(childEntityTypes);

			RenderParentEntityTypePickList(nsswf, controls, 10, y + 25);
			RenderChildEntityTypePickList(nsswf, controls, 10, y + 50);
			RopButton(nsswf, controls, "Associate", "{App.OnAssociate}", 10, y + 75);
			RopGrid(nsswf, controls, 10, y + 100, "grid2");

			// The part of the UI for navigating to parent/child instances:
			RenderNavParentEntityTypePickList(nsswf, controls, 280, 80);
			RenderNavChildEntityTypePickList(nsswf, controls, 280, 150);

			string xml = xdoc.ToString();
			Clipboard.SetText(xml);						// for debugging.

			// Parser.AddExtender("MyXaml.WinForms", "MyXaml.WinForms", "WinFormExtender");
			Parser p = new Parser();
			p.AddReference("EventHandlers", eventHandlers);
			p.AddReference("parentEntityTypes", parentEntityTypes);
			p.AddReference("childEntityTypes", childEntityTypes);
			p.AddReference("navParentEntityTypes", navParentEntityTypes);
			p.AddReference("navChildEntityTypes", navChildEntityTypes);
			Form form = (Form)p.InstantiateFromString(xml, "*");
			p.InitializeFields(this, true);
			p.InitializeFields(eventHandlers, true);

			BindingSource bs;
			bs = new BindingSource();
			bs.DataSource = dataSet.DataView;
			IGrid dgv = null;

			// Set up the DataGridView if we are displaying one.
			if ((renderMode == Mode.Grid) || (renderMode == Mode.Hybrid))
			{
				dgv = grid1;
				dgv.DataSource = bs;
			}

			if ((renderMode == Mode.Hybrid) || (renderMode == Mode.Discrete))
			{
				BindControls(p, bs, dataSet.Attributes);
			}

			if (renderMode == Mode.Discrete)
			{
				BindingNavigator nav = (BindingNavigator)p.GetReference("nav1");
				nav.AddStandardItems();
				nav.BindingSource = bs;
			}

			eventHandlers.GridInfo.BindingSource=bs;
			eventHandlers.GridInfo.Grid = dgv;

			dataSet.LoadTable(PKList);

			form.Show();
		}

		protected void RenderParentEntityTypePickList(XNamespace nsswf, XElement controls, int x, int y)
		{
			RopCombobox(nsswf, controls, "Child Of:", "parentEntityTypes", "EntityTypeID", "EntityTypeName", x, y, "cbParentEntities");
			RopButton(nsswf, controls, "Show Data", "{EventHandlers.OnShowParentData}", x + 230, y);
		}	

		protected void RenderChildEntityTypePickList(XNamespace nsswf, XElement controls, int x, int y)
		{
			RopCombobox(nsswf, controls, "Parent Of:", "childEntityTypes", "EntityTypeID", "EntityTypeName", x, y, "cbChildEntities");
			RopButton(nsswf, controls, "Show Data", "{EventHandlers.OnShowChildData}", x + 230, y);
		}

		protected void RenderNavParentEntityTypePickList(XNamespace nsswf, XElement controls, int x, int y)
		{
			RopCombobox(nsswf, controls, "To Parent:", "navParentEntityTypes", "EntityTypeID", "EntityTypeName", x, y, "cbNavParent", "Top, Right");
			RopButton(nsswf, controls, "Go", "{EventHandlers.OnNavToParent}", x + 60, y + 25, "Top, Right");
		}

		protected void RenderNavChildEntityTypePickList(XNamespace nsswf, XElement controls, int x, int y)
		{
			RopCombobox(nsswf, controls, "To Child:", "navChildEntityTypes", "EntityTypeID", "EntityTypeName", x, y, "cbNavChild", "Top, Right");
			RopButton(nsswf, controls, "Go", "{EventHandlers.OnNavToChild}", x + 60, y + 25, "Top, Right");
		}

		/// <summary>
		/// Returns the relationship type ID given two entity type instance ID's.
		/// </summary>
		protected void CreateDiscreteControls(XNamespace nsswf, XElement controls, List<AttributeInfo> attributes, ref int x, ref int y)
		{
			int n = 0;

			foreach (AttributeInfo attrInfo in attributes)
			{
				RopLabel(nsswf, controls, attrInfo, ref x, ref y);
				RopTextBox(nsswf, controls, attrInfo, ref x, ref y, "ctrl" + n++);
				x = 10;
				y += 5;
			}
		}

		protected void BindControls(Parser p, BindingSource bs, List<AttributeInfo> attributes)
		{
			int n = 0;

			foreach (AttributeInfo attrInfo in attributes)
			{
				string ctrlName = "ctrl" + n;
				string colName="col"+n;
				n++;
				Control ctrl = (Control)p.GetReference(ctrlName);
				ctrl.DataBindings.Add("Text", bs, colName);
			}
		}

		protected void RopLabel(XNamespace ns, XElement controls, AttributeInfo attrInfo, ref int x, ref int y)
		{
			controls.Add(new XElement(ns + "Label",
				new XAttribute("Location", x + ", " + (y + 3)),
				new XAttribute("Text", attrInfo.Name + ":")));

			x += 100;
		}

		protected void RopLabel(XNamespace ns, XElement controls, string text, int x, int y, string anchor)
		{
			controls.Add(new XElement(ns + "Label",
				new XAttribute("Location", x + ", " + (y + 3)),
				new XAttribute("AutoSize", "true"),
				new XAttribute("Anchor", anchor),
				new XAttribute("Text", text)));
		}

		protected void RopTextBox(XNamespace ns, XElement controls, AttributeInfo attrInfo, ref int x, ref int y, string name)
		{
			XNamespace nsdef = "Definition";

			if (attrInfo.Length < 60)
			{
				// Single line control.
				controls.Add(new XElement(ns + "TextBox",
					new XAttribute("Location", x + "," + y),
					new XAttribute("Size", "150, 20"),
					new XAttribute(nsdef + "Name", name),
					new XAttribute("MaxLength", attrInfo.Length)));

				y+=20;
			}
			else
			{
				// Multiline control.
				controls.Add(new XElement(ns + "TextBox",
					new XAttribute("Location", x + "," + y),
					new XAttribute("Size", "250, 100"),
					new XAttribute("MaxLength", attrInfo.Length),
					new XAttribute("Multiline", true),
					new XAttribute(nsdef + "Name", name),
					new XAttribute("AcceptsReturn", true)));

				x += 150;
				y += 100;
			}
		}

		protected void RopGrid(XNamespace ns, XElement controls, int x, int y, string name)
		{
			XNamespace nsdef = "Definition";
			controls.Add(new XElement(ns + "DataGridView",
				new XAttribute(nsdef + "Name", name),
				new XAttribute("Location", x + "," + y),
				new XAttribute("Size", "450, 170"),
				new XAttribute("Anchor", "Top, Left, Bottom, Right")));

			y += 200;
		}

		protected void RopGrid(XNamespace ns, XElement controls, List<AttributeInfo> attributes, ref int x, ref int y, string anchor, string name)
		{
			XNamespace nsdef="Definition";
			controls.Add(new XElement(ns + "DataGridView",
				new XAttribute(nsdef + "Name", name),
				new XAttribute("Location", x + "," + y),
				new XAttribute("Size", "250, 170"),
				new XAttribute("Anchor", anchor)));

			y += 200;
		}

		protected void RopBindingNavigator(XNamespace ns, XElement controls, ref int x, ref int y)
		{
			XNamespace nsdef = "Definition";
			controls.Add(new XElement(ns + "BindingNavigator",
				new XAttribute(nsdef + "Name", "nav1"),
				new XAttribute("Dock", "Top")));

			y += 30;
		}

		protected void RopButton(XNamespace ns, XElement controls, string text, string eventName, int x, int y, string anchor="Top, Left")
		{
			controls.Add(new XElement(ns + "Button",
				new XAttribute("Location", x + "," + y),
				new XAttribute("Size", "80, 25"),
				new XAttribute("Text", text),
				new XAttribute("Anchor", anchor),
				new XAttribute("Click", eventName)));
		}

		protected void RopNewButton(XNamespace ns, XElement controls)
		{
			controls.Add(new XElement(ns + "Button",
				new XAttribute("Location", "420, 40"),
				new XAttribute("Size", "70, 25"),
				new XAttribute("Text", "&New"),
				new XAttribute("Anchor", "Top, Right"),
				new XAttribute("Click", "{EventHandlers.OnNew}")));
		}

		protected void RopSaveButton(XNamespace ns, XElement controls, int y)
		{
			controls.Add(new XElement(ns + "Button",
				new XAttribute("Location", "420, " + y),
				new XAttribute("Size", "70, 25"),
				new XAttribute("Text", "&Save"),
				new XAttribute("Anchor", "Top, Right"),
				new XAttribute("Click", "{EventHandlers.OnSave}")));
		}

		protected void RopCombobox(XNamespace nsswf, XElement controls, string label, string listName, string valueField, string displayField, int x, int y, string name, string anchor="Top, Left")
		{
			RopLabel(nsswf, controls, label, x, y, anchor);
			XNamespace nsdef = "Definition";

			controls.Add(new XElement(nsswf + "ComboBox",
				new XAttribute(nsdef + "Name", name),
				new XAttribute("Location", (x + 60) + ", " + y),
				new XAttribute("Width", "150"),
				new XAttribute("Anchor", anchor),
				new XAttribute("ValueMember", valueField),
				new XAttribute("DisplayMember", displayField),
				new XAttribute("DataSource", "{" + listName + "}")));
		}
	}
}

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
Architect Interacx
United States United States
Blog: https://marcclifton.wordpress.com/
Home Page: http://www.marcclifton.com
Research: http://www.higherorderprogramming.com/
GitHub: https://github.com/cliftonm

All my life I have been passionate about architecture / software design, as this is the cornerstone to a maintainable and extensible application. As such, I have enjoyed exploring some crazy ideas and discovering that they are not so crazy after all. I also love writing about my ideas and seeing the community response. As a consultant, I've enjoyed working in a wide range of industries such as aerospace, boatyard management, remote sensing, emergency services / data management, and casino operations. I've done a variety of pro-bono work non-profit organizations related to nature conservancy, drug recovery and women's health.

Comments and Discussions