⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlloader.cs

📁 SharpDevelop2.0.0 c#开发免费工具
💻 CS
字号:
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
//     <version>$Revision: 1330 $</version>
// </file>

using System;
using System.IO;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Text;
using System.Text.RegularExpressions;

namespace ICSharpCode.SharpDevelop.Gui.XmlForms 
{
	/// <summary>
	/// This class is able to generate a GUI definition out of a XML file.
	/// </summary>
	public class XmlLoader
	{
		Dictionary<string, Control> controlDictionary = new Dictionary<string, Control>();
		object            customizationObject;
		
		
		// required for the accept/cancel button/tooltips workaround
		Form mainForm = null;
		
		Hashtable tooltips      = new Hashtable();
		string acceptButtonName = String.Empty;
		string cancelButtonName = String.Empty;
		
		IStringValueFilter    stringValueFilter    = null;
		IObjectCreator        objectCreator        = new DefaultObjectCreator();
		IPropertyValueCreator propertyValueCreator = null;
		
		readonly static Regex propertySet  = new Regex(@"(?<Property>[\w]+)\s*=\s*(?<Value>[\w\d]+)", RegexOptions.Compiled);
		
		/// <summary>
		/// Gets the ControlDictionary for this XmlLoader.
		/// </summary>
		public Dictionary<string, Control> ControlDictionary {
			get {
				return controlDictionary;
			}
		}
		
		/// <summary>
		/// Gets/Sets the IStringValueFilter, could be set to <code>null</code> 
		/// (for not filtering the values).
		/// </summary>
		public IStringValueFilter StringValueFilter {
			get {
				return stringValueFilter;
			}
			set {
				stringValueFilter = value;
			}		
		}
		
		/// <summary>
		/// Gets/Sets the IObjectCreator, could NOT be set to <code>null</code>.
		/// </summary>
		public IObjectCreator ObjectCreator {
			get {
				return objectCreator;
			}
			set {
				if (value == null) {
					throw new System.ArgumentNullException();
				}
				objectCreator = value;
			}		
		}
		
		/// <summary>
		/// Gets/Sets the IPropertyValueCreator, could be set to <code>null</code>.
		/// </summary>
		public IPropertyValueCreator PropertyValueCreator {
			get {
				return propertyValueCreator;
			}
			set {
				propertyValueCreator = value;
			}		
		}
		
		
		/// <summary>
		/// Creates a new instance of XmlLoader.
		/// </summary>
		public XmlLoader()
		{
		}
		
		public T Get<T>(string name) where T: System.Windows.Forms.Control
		{
			string key = name + typeof(T).Name;
			if (!ControlDictionary.ContainsKey(key)) {
				throw new System.ArgumentException("Control " + key + " not found!", "name");
			}

			return ControlDictionary[key] as T;
		}
		
#region Load/Create functions		
		/// <summary>
		/// Loads the XML definition from fileName and sets creates the control.
		/// </summary>
		/// <param name="fileName">
		/// The filename of the XML definition file to load.
		/// </param>
		public object CreateObjectFromFileDefinition(string fileName)
		{
			XmlDocument doc = new XmlDocument();
			doc.Load(fileName);
			
			XmlElement el = doc.DocumentElement;
			
			if (doc.DocumentElement.Attributes["version"] != null) {
				el = (XmlElement)doc.DocumentElement.ChildNodes[0];
			}

			customizationObject = objectCreator.CreateObject(XmlConvert.DecodeName(el.Name), el);
			
			SetUpObject(customizationObject, el);
			return customizationObject;
		}
		
		/// <summary>
		/// Loads the XML definition from a xml definition and sets creates the control.
		/// </summary>
		public object CreateObjectFromXmlDefinition(string xmlContent)
		{
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(xmlContent);
			
			XmlElement el = doc.DocumentElement;
			if (doc.DocumentElement.Attributes["version"] != null) {
				el = (XmlElement)doc.DocumentElement.ChildNodes[0];
			}

			customizationObject = objectCreator.CreateObject(XmlConvert.DecodeName(el.Name), el);
			
			SetUpObject(customizationObject, el);
			return customizationObject;
		}

		/// <summary>
		/// Loads the XML definition from fileName and sets creates the control.
		/// </summary>
		/// <param name="customizationObject">
		/// The object to customize. (should be a control or form)
		/// This is object, because this class may be extended later.
		/// </param>
		/// <param name="fileName">
		/// The filename of the XML definition file to load.
		/// </param>
		public void LoadObjectFromFileDefinition(object customizationObject, string fileName)
		{
			XmlDocument doc = new XmlDocument();
			doc.Load(fileName);
			LoadObjectFromXmlDocument(customizationObject, doc);
		}
		public void LoadObjectFromStream(object customizationObject, Stream stream)
		{
			XmlDocument doc = new XmlDocument();
			doc.Load(stream);
			LoadObjectFromXmlDocument(customizationObject, doc);
		}
		
		public void LoadObjectFromXmlDocument(object customizationObject, XmlDocument doc)
		{
			this.customizationObject = customizationObject;
			
			XmlElement el = doc.DocumentElement;
			if (doc.DocumentElement.Attributes["version"] != null) {
				el = (XmlElement)doc.DocumentElement.ChildNodes[0];
			}

			SetUpObject(customizationObject, el);
			
			// little HACK to set the Accept & Cancel Button
			if (customizationObject is Form) {
				Form mainForm = (Form)customizationObject;
				if (acceptButtonName != null && acceptButtonName.Length > 0) {
					mainForm.AcceptButton = (Button)controlDictionary[acceptButtonName];
				}
				if (cancelButtonName != null && cancelButtonName.Length > 0) {
					mainForm.CancelButton = (Button)controlDictionary[cancelButtonName];
				}
			}
			// little HACK to set the Tooltips...
			if (tooltips.Count > 0) {
				ToolTip toolTip = new ToolTip();
				foreach (DictionaryEntry entry in tooltips) {
					toolTip.SetToolTip((Control)entry.Key, entry.Value.ToString());
				}
			}
		}
		
		/// <summary>
		/// Loads the XML definition from a xml definition and sets creates the control.
		/// </summary>
		public void LoadObjectFromXmlDefinition(string xmlContent)
		{
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(xmlContent);
			
			XmlElement el = doc.DocumentElement;
			if (doc.DocumentElement.Attributes["version"] != null) {
				el = (XmlElement)doc.DocumentElement.ChildNodes[0];
			}
			SetUpObject(customizationObject, doc.DocumentElement);
		}
#endregion

		/// <summary>
		/// Sets the properties of an object <code>currentObject</code> to the
		/// contents of the xml element <code>element</code>
		/// </summary>
		void SetUpObject(object currentObject, XmlElement element)
		{
			foreach (XmlNode subNode in element.ChildNodes) {
				if (subNode is XmlElement){
					XmlElement subElement = (XmlElement)subNode;
					SetAttributes(currentObject, subElement);
				}
			}
			
			if (currentObject is Control) {
				((Control)currentObject).ResumeLayout(false);
			}
		}
		
		string acceptButton = "";
		string cancelButton = "";
		/// <summary>
		/// Sets a property called propertyName in object <code>o</code> to <code>val</code>. This method performs
		/// all neccessary casts.
		/// </summary>
		void SetValue(object o, string propertyName, string val)
		{
			try {
				PropertyInfo propertyInfo = o.GetType().GetProperty(propertyName);
				if (propertyName == "AcceptButton") {
					this.acceptButton = val.Split(' ')[0];
					return;
				}
				
				if (propertyName == "CancelButton") {
					this.cancelButton = val.Split(' ')[0];
					return;
				}
				
				if (propertyName == "ToolTip") {
					tooltips[o] = val;
					return;
				}
				
				if (val.StartsWith("{") && val.EndsWith("}")) {
					val = val.Substring(1, val.Length - 2);
					object propertyObject = null;
					if (propertyInfo.CanWrite) {
						Type type = objectCreator.GetType(propertyInfo.PropertyType.FullName);
						propertyObject = type.Assembly.CreateInstance(propertyInfo.PropertyType.FullName);
					} else {
						propertyObject = propertyInfo.GetValue(o, null);
					}
					
					Match match = propertySet.Match(val);
					while (true) {
						if (!match.Success) {
							break;
						}
						SetValue(propertyObject, match.Result("${Property}"), match.Result("${Value}"));
						match = match.NextMatch();
					}
					
					if (propertyInfo.CanWrite) {
						propertyInfo.SetValue(o, propertyObject, null);
					}
					
				} else if (propertyInfo.PropertyType.IsEnum) {
					propertyInfo.SetValue(o, Enum.Parse(propertyInfo.PropertyType, val), null);
				} else if (propertyInfo.PropertyType == typeof(Color)) {
					string color = val.Substring(val.IndexOf('[') + 1).Replace("]", "");
					string[] argb = color.Split(',', '=');
					if (argb.Length > 1) {
						propertyInfo.SetValue(o, Color.FromArgb(Int32.Parse(argb[1]), Int32.Parse(argb[3]), Int32.Parse(argb[5]), Int32.Parse(argb[7])), null);
					} else {
						propertyInfo.SetValue(o, Color.FromName(color), null);
					}
				} else {
					if (val.Length > 0) {
						TypeConverter conv = TypeDescriptor.GetConverter(propertyInfo.PropertyType);
						propertyInfo.SetValue(o, conv.ConvertFromInvariantString(val), null);
					}
				}
			} catch (Exception e) {
				throw new ApplicationException("error while setting property " + propertyName + " of object "+ o.ToString() + " to value '" + val+ "'", e);
			}
		}
		
		/// <summary>
		/// Sets all properties in the object <code>o</code> to the xml element <code>el</code> defined properties.
		/// </summary>
		void SetAttributes(object o, XmlElement el)
		{
			if (el.Name == "AcceptButton") {
				mainForm = (Form)o;
				acceptButtonName = el.Attributes["value"].InnerText.Split(' ')[0];
				return;
			}
			
			if (el.Name == "CancelButton") {
				mainForm = (Form)o;
				cancelButtonName = el.Attributes["value"].InnerText.Split(' ')[0];
				return;
			}
			
			if (el.Name  == "ToolTip") {
				string val = el.Attributes["value"].InnerText;
				tooltips[o] = stringValueFilter != null ? stringValueFilter.GetFilteredValue(val) : val;
				return;
			}
				

			if (el.Attributes["value"] != null) {
				string val = el.Attributes["value"].InnerText;
				try {
					SetValue(o, el.Name, stringValueFilter != null ? stringValueFilter.GetFilteredValue(val) : val);
				} catch (Exception) {}
			} else if (el.Attributes["event"] != null) {
				try {
					EventInfo eventInfo = o.GetType().GetEvent(el.Name);
					eventInfo.AddEventHandler(o, Delegate.CreateDelegate(eventInfo.EventHandlerType, customizationObject, el.Attributes["event"].InnerText));
				} catch (Exception) {}
			} else {
				PropertyInfo propertyInfo = o.GetType().GetProperty(el.Name);
				object pv = propertyInfo.GetValue(o, null);
				if (pv is IList) {
					foreach (XmlNode subNode in el.ChildNodes) {
						if (subNode is XmlElement){
							XmlElement subElement = (XmlElement)subNode;
							object collectionObject = objectCreator.CreateObject(XmlConvert.DecodeName(subElement.Name), subElement);
							if (collectionObject == null) {
								continue;
							}
							if (collectionObject is IComponent) {
								string name = null;
								if (subElement["Name"] != null &&
								    subElement["Name"].Attributes["value"] != null) {
								    name = subElement["Name"].Attributes["value"].InnerText;
								}
								    
								if (name == null || name.Length == 0) {
									name = "CreatedObject" + num++;
								}
//								collectionObject =  host.CreateComponent(collectionObject.GetType(), name);
							}
							
							SetUpObject(collectionObject, subElement);
							
							if (collectionObject is Control) {
								string name = ((Control)collectionObject).Name;
								if (name != null && name.Length > 0) {
									ControlDictionary[name] = (Control)collectionObject;
								}
							}
							
							if (collectionObject != null) {
								((IList)pv).Add(collectionObject);
							} 
							
							
						}
					}
				} else {
					object propertyObject = objectCreator.CreateObject(o.GetType().GetProperty(el.Name).PropertyType.Name, el);
					if (propertyObject is IComponent) {
						PropertyInfo pInfo = propertyObject.GetType().GetProperty("Name");
						string name = null;
						if (el["Name"] != null &&
						    el["Name"].Attributes["value"] != null) {
						    name = el["Name"].Attributes["value"].InnerText;
						}
											
						if (name == null || name.Length == 0) {
							name = "CreatedObject" + num++;
						}
						propertyObject = objectCreator.CreateObject(name, el);
					}
					SetUpObject(propertyObject, el);
					propertyInfo.SetValue(o, propertyObject, null);
				}
			}
		}
		int num = 0;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -