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

The Application Automation Layer - Using XML to generate Menus

Rate me:
Please Sign up or sign in to vote.
4.81/5 (56 votes)
5 May 200313 min read 238.3K   2.6K   194  
Exploring the issues of menu management as specified externally via an XML file, in the context of status bars, toolbars, and events.
using System;
using System.Data;
using System.IO;
using System.Xml;

/*
	Some documentation:
	
		XSD files:
		
			appInfo.xsd		The application information schema.  This file specified as a command line parameter.
							There is one record in this file.
				FormFile - the XML file specifying the list of forms
				MenuFile - the XML file specifying the menu structure
				AppType - the application type
				MainFormName - the startup form name
				
			components.xsd		Component and published interface definitions
							
			formList.xsd		The list of form specification files to load schema
							There are multiple records, one per filename
				Name - the XML filename containing form information
				
			menus.xsd			The menu structure schema
			
			forms.xsd			The form and component schema
*/

/*
	Manifest:
		http://www.codeproject.com/useritems/xptheme.asp
		http://www.codeproject.com/csharp/dotnetvisualstyles.asp
		
	Menus:
		http://www.codeproject.com/useritems/MenuImage.asp
			Some modifications--menu items are dynamically generated, so Component model isn't required
			Added image margin color.
		http://www.codeproject.com/cs/menu/vsnetmenu.asp
		
	Grid Control:
		http://www.codeproject.com/useritems/CSharpGridControl.asp
		
	MDI Forms:
		http://www.codeproject.com/csharp/mdiformstutorial.asp
		
	Saving and restoring window state:
		http://www.dotnet247.com/247reference/a.aspx?u=http://www.c-sharpcorner.com/Code/2002/Mar/SavingNRestoringWinJM.asp
		
	Rebar control wrapper:
		http://www.codeproject.com/cs/menu/rebarcontrol.asp
		
	Outlook bar:
		http://www.codeproject.com/cs/miscctrl/OutlookBar.asp

	Progress bar:
		http://www.codeproject.com/cs/miscctrl/progressbar.asp		
		
	Toolbar:
		http://www.codeproject.com/cs/menu/vsnettoolbar.asp

	Expression evaluators:
		http://www.codeproject.com/csharp/runtime_eval.asp?target=expression%7Cevaluator
		http://www.codeproject.com/useritems/math_expression_evaluator.asp?target=expression%7Cevaluator		
		
	*** Take a look at this: ***
		http://www.altova.com/features_code.html
		http://www.devexpress.com/index.shtm
		http://www.sellsbrothers.com/tools/

	Issues:
		flatstyle and buttons with bitmap images are not compatible
			(CPian Chris Jobson pointed out to use an ImageList and then specify which color is the transparent color)
		status bar raised and sunken seem to be the same
*/

/*
 * Things to do/write about
 *	toolbars
 *	menu item / toolbar state coupling
 *   form icons
 *   save/restore window state
 *   window list
 *   control anchors (panels)
 *   tab order
 *	autosizing of dialogs
 *	making a dialog look like a dialog box--no min/max.  no sizing.  no icons
 *	default accept/cancel button (AcceptButton and CancelButton)
 *	help button?  (Form.HelpButton)
 *	radiobuttons automatically grouped into the parent group box
 *	using CreateParams in label to set justification
 * 
 *	Need an article discussing toolbars, status bars, need for panels within forms (frame/view architecture),
 *		what happens when you add a status bar, how it affects anchors, panel sizes, etc.
 * 
 *	Design By Contract
 *	AOP-for example, automatically changing the cursor to a wait for slow methods, or adding debugging/logging
 *	!!! This can easily be done with the AAL architecture's invoke abstraction !!!
 */

namespace AAL
{
	public sealed class WindowFormManager
	{
		public static WindowFormManager wfm;
		private static ICore.IComponentManager icm;
		private static ICore.IDataHub idh;

		private IWFM iwfm;
		private XmlDataDocument doc;
		private FormMgr formMgr;
		private string formSpec="";

		public FormMgr FormMgr
		{
			get
			{
				return formMgr;
			}
		}

		/// <summary>
		/// Phase 1 initialization.
		/// </summary>
		/// <param name="icm">The Component Manager interface.</param>
		/// <returns></returns>
		public static ICore.IWindowFormManager Init1(ICore.IComponentManager icm)
		{
			WindowFormManager.icm=icm;
			wfm=new WindowFormManager();
			wfm.formMgr=new FormMgr(wfm);
			return wfm.iwfm;
		}

		/// <summary>
		/// Phase 2 initialization.
		/// </summary>
		public static void Init2()
		{
			idh=icm.GetInterface("DataHub") as ICore.IDataHub;
			wfm.formMgr.ICM=icm;
			wfm.formMgr.IDH=idh;
		}

		/// <summary>
		/// Constructor.
		/// </summary>
		public WindowFormManager()
		{
			Dbg.Problems.Add(
				new DbgKey("DupForm"),
				"",
				new string[] {"This form already exists."});
			Dbg.Problems.Add(
				new DbgKey("UnkForm"),
				"",
				new string[] {"Unknown form."});
			Dbg.Problems.Add(
				new DbgKey("UnkChildForm"),
				"",
				new string[] {"Unknown MDI child form."});
			Dbg.Problems.Add(
				new DbgKey("IntUnkForm"),
				"",
				new string[] {"Internal error -- unknown form."});
			Dbg.Problems.Add(
				new DbgKey("UnkName"),
				"",
				new string[] {"Unknown name."});
			Dbg.Problems.Add(
				new DbgKey("UnkCtrl"),
				"",
				new string[] {"Unknown control."});
			Dbg.Problems.Add(
				new DbgKey("NoFormInfo"),
				"",
				new string[] {"No information available for the requested form."});
			Dbg.Problems.Add(
				new DbgKey("FrmHdr"),
				"",
				new string[] {"The header block is missing required information."});
			Dbg.Problems.Add(
				new DbgKey("NoMenuForForm"),
				"",
				new String[] {"The specified form does not support menus."});
			Dbg.Problems.Add(
				new DbgKey("NotMDIForm"),
				"",
				new String[] {"The master form is not an MDI form."});

			iwfm=new IWFM(this);

			StreamReader tr=new StreamReader("forms.xsd");
			Dbg.Assert(tr != null, new DbgKey("MissingXSDFile"));
			doc=new XmlDataDocument();
			doc.DataSet.ReadXmlSchema(tr);
			tr.Close();

//			icm.RegisterInterfacePoint("WindowFormManager", "LoadForms", new InterfacePoint(LoadForms));
		}

		public void LoadFormSpecifications(string xmlFileName)
		{
			StreamReader sr2=new StreamReader(xmlFileName);
			// skip <NewDatSet> tag
			sr2.ReadLine();							
			string newStr=sr2.ReadToEnd();
			// For some reason, the EOF character shows up on my desktop XP system, but not my laptop XP.
			// newStr=newStr.TrimEnd(new char[] {(char)0x1A});
			// remove ending </NewDataSet> tag
			int i=newStr.Length-1;
			while (newStr[i] != '<') --i;
			newStr=newStr.Substring(0, i-1);
			formSpec=formSpec+newStr;
			sr2.Close();			
		}

		public void SyncDataSet()
		{
			StringReader sr=new StringReader(formSpec);
			doc.Load(sr);
			sr.Close();
		}

		public object LoadForms(EventData eventData)
		{
			formSpec+="<NewDataSet>\r\n";
			string formList;
			eventData.UnMarshal("FormList", out formList);
			XmlDataDocument formDoc=new XmlDataDocument();
			StreamReader tr=new StreamReader("formList.xsd");
			formDoc.DataSet.ReadXmlSchema(tr);
			tr.Close();
			formDoc.Load(formList);
			DataTable dt=formDoc.DataSet.Tables["Form"];
			foreach (DataRow row in dt.Rows)
			{
				LoadFormSpecifications((string)row["Name"]);
			}
			formSpec+="</NewDataSet>\r\n";
			StreamWriter sw=new StreamWriter("appForms.xml");
			sw.Write(formSpec);
			sw.Flush();
			sw.Close();
			SyncDataSet();
			return null;
		}

		public XmlDataDocument Doc
		{
			get {return doc;}
		}
	}
}

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


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