/// <summary>
 /// Returns a Hashtable containing the key and filename of each file that is registered in the specified configuration
 /// </summary>
 /// <param name="configuration">The configuration in which the search will occur</param>
 /// <returns></returns>
 public static Hashtable GetRegisteredFiles(XmlConfiguration configuration)
 {
     ConfigurationEngine.ResetLastException();
     try
     {
         if (configuration != null)
         {
             XmlConfigurationCategory category = configuration.Categories[CategoryNames.Files.ToString()];
             if (category != null)
             {
                 Hashtable table = new Hashtable();
                 foreach (XmlConfigurationOption option in category.Options)
                 {
                     table.Add(option.ElementName, (string)option.Value);
                 }
                 return(table);
             }
         }
     }
     catch (System.Exception systemException)
     {
         _lastException = systemException;
         System.Diagnostics.Trace.WriteLine(systemException);
     }
     return(new Hashtable());
 }
Exemple #2
0
        /// <summary>
        /// Finds an existing node for the specified category
        /// </summary>
        /// <param name="nodes"></param>
        /// <param name="category"></param>
        /// <returns></returns>
        private CategoryTreeNode FindNodeForCategory(TreeNodeCollection nodes, XmlConfigurationCategory category)
        {
            if (this.InvokeRequired)
            {
                return(this.Invoke(new FindNodeForCategoryInvoker(this.FindNodeForCategory), new object[] { nodes, category }) as CategoryTreeNode);
            }

            if (nodes == null)
            {
                // asume root
                nodes = _treeView.Nodes;
            }

            if (nodes != null)
            {
                if (category != null)
                {
                    foreach (CategoryTreeNode n in nodes)
                    {
                        //						if (n.IsBoundToCategory(category))
                        //							return n;
                        if (string.Compare(n.Text, category.DisplayName, true) == 0)
                        {
                            return(n);
                        }
                    }
                }
            }
            return(null);
        }
        /// <summary>
        /// Writes a category to the XmlDocument
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="parent"></param>
        /// <param name="category"></param>
        /// <param name="alwaysPersist"></param>
        private void WriteCategory(XmlDocument doc, XmlElement parent, XmlConfigurationCategory category, bool alwaysPersist)
        {
            try
            {
                if (category.Persistent || alwaysPersist)
                {
                    /// create an element for the category
                    XmlElement child = doc.CreateElement(@"Category");

                    /// write the properties of this category
                    child.SetAttribute(@"ElementName", category.ElementName);
                    child.SetAttribute(@"HasChanges", XmlConvert.ToString(category.HasChanges));
                    child.SetAttribute(@"Category", category.Category);
                    child.SetAttribute(@"Description", category.Description);
                    child.SetAttribute(@"DisplayName", category.DisplayName);
                    child.SetAttribute(@"Hidden", XmlConvert.ToString(category.Hidden));

                    /// append the child to our parent
                    parent.AppendChild(child);

                    /// write the options into the category
                    this.WriteOptions(doc, child, category.Options, alwaysPersist);

                    /// write recursively into the categories
                    this.WriteCategories(doc, child, category.Categories, alwaysPersist);
                }
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
            }
        }
Exemple #4
0
        /// <summary>
        /// Returns a clone of this category
        /// </summary>
        /// <returns></returns>
        public new XmlConfigurationCategory Clone()
        {
            XmlConfigurationCategory clone   = null;
            XmlConfigurationElement  element = (XmlConfigurationElement)base.Clone();

            if (element != null)
            {
                clone = new XmlConfigurationCategory(element);
                clone.ResetBeforeEdit();
                clone.ResetChanged();
                clone.ResetAfterEdit();
                clone.ResetEditCancelled();

                if (_options != null)
                {
                    clone.Options = (XmlConfigurationOptionCollection)_options.Clone();
                }

                if (_categories != null)
                {
                    clone.Categories = (XmlConfigurationCategoryCollection)_categories.Clone();
                }
            }
            return(clone);
        }
        /// <summary>
        /// Registers the file using the specified key in the specified configuration. If the key already exists, the file will be written to the existing key.
        /// </summary>
        /// <param name="configuration">The configuration in which the file will be registered</param>
        /// <param name="key">The key by which the file will be registered</param>
        /// <param name="filename">The filename that will be registered</param>
        /// <returns></returns>
        public static bool RegisterFile(XmlConfiguration configuration, string key, string filename)
        {
            ConfigurationEngine.ResetLastException();
            try
            {
                if (configuration != null)
                {
                    if (key != null && key != string.Empty)
                    {
                        XmlConfigurationCategory category = configuration.Categories[CategoryNames.Files.ToString()];
                        if (category != null)
                        {
                            XmlConfigurationOption option = null;

                            option = category.Options[key];
                            if (option == null)
                            {
                                option             = category.Options[key, true, filename];
                                option.Category    = @"Registered Files";
                                option.Description = @"This indicates a configuration file that is registered and ready to be accessed via the ConfigurationEngine.";
                            }
                            option.Value = filename;
                            return(true);
                        }
                    }
                }
            }
            catch (System.Exception systemException)
            {
                _lastException = systemException;
                System.Diagnostics.Trace.WriteLine(systemException);
            }
            return(false);
        }
        /// <summary>
        /// Returns the filename using the specified key from the specified configuration
        /// </summary>
        /// <param name="configuration">The configuration from which the filename will be extracted</param>
        /// <param name="key">The key by which the filename was saved</param>
        /// <returns></returns>
        public static string GetRegisteredFilename(XmlConfiguration configuration, string key)
        {
            ConfigurationEngine.ResetLastException();
            try
            {
                if (configuration != null)
                {
                    if (key != null && key != string.Empty)
                    {
                        XmlConfigurationCategory category = configuration.Categories[CategoryNames.Files.ToString()];
                        if (category != null)
                        {
                            XmlConfigurationOption option = null;

                            option = category.Options[key];
                            if (option != null)
                            {
                                return((string)option.Value);
                            }
                        }
                    }
                }
            }
            catch (System.Exception systemException)
            {
                _lastException = systemException;
                System.Diagnostics.Trace.WriteLine(systemException);
            }
            return(string.Empty);
        }
Exemple #7
0
 /// <summary>
 /// Determines if the category is bound to the node
 /// </summary>
 /// <param name="category">The category to check bindings for</param>
 /// <returns></returns>
 public bool IsBoundToCategory(XmlConfigurationCategory category)
 {
     if (category != null)
     {
         return(_table.ContainsKey(category.Fullpath));
     }
     return(false);
 }
		/// <summary>
		/// Binds a category to the node, returns false if the category is already bound
		/// </summary>
		/// <param name="category">The category to bind to the node</param>
		/// <returns></returns>
		public bool BindToCategory(XmlConfigurationCategory category)
		{
			if (!this.IsBoundToCategory(category))
			{
				_table.Add(category.Fullpath, category);
				return true;
			}
			return false;
		}
Exemple #9
0
 /// <summary>
 /// Binds a category to the node, returns false if the category is already bound
 /// </summary>
 /// <param name="category">The category to bind to the node</param>
 /// <returns></returns>
 public bool BindToCategory(XmlConfigurationCategory category)
 {
     if (!this.IsBoundToCategory(category))
     {
         _table.Add(category.Fullpath, category);
         return(true);
     }
     return(false);
 }
Exemple #10
0
        public void Add(string elementName)
        {
            XmlConfigurationCategory category = null;

            if (!this.Contains(elementName))
            {
                category = new XmlConfigurationCategory(elementName);
                this.Add(category);
            }
        }
Exemple #11
0
        public bool Contains(XmlConfigurationCategory category)
        {
            foreach (XmlConfigurationCategory c in base.InnerList)
            {
                if (c.ElementName == category.ElementName)
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #12
0
 public void Remove(XmlConfigurationCategory category)
 {
     if (this.Contains(category))
     {
         category.BeforeEdit    -= new XmlConfigurationElementCancelEventHandler(this.OnBeforeEdit);
         category.Changed       -= new XmlConfigurationElementEventHandler(this.OnChanged);
         category.AfterEdit     -= new XmlConfigurationElementEventHandler(this.OnAfterEdit);
         category.EditCancelled -= new XmlConfigurationElementEventHandler(this.OnEditCancelled);
         base.InnerList.Remove(category);
         this.OnChanged(this, new XmlConfigurationCategoryEventArgs(category, XmlConfigurationElementActions.Removed));
     }
 }
Exemple #13
0
        public XmlConfigurationCategory this[string keyOrPath, bool createIfNotFound]
        {
            get
            {
                string[] categories = keyOrPath.Split(XmlConfiguration.CategoryPathSeparators);
                foreach (XmlConfigurationCategory category in base.InnerList)
                {
                    if (category.ElementName == categories[0])
                    {
                        if (categories.Length == 1)
                        {
                            return(category);
                        }
                        else
                        {
                            keyOrPath = string.Join(XmlConfiguration.DefaultPathSeparator, categories, 1, categories.Length - 1);
                        }

                        XmlConfigurationCategory subCategory = category.Categories[keyOrPath];
                        if (subCategory != null)
                        {
                            return(subCategory);
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                if (createIfNotFound)
                {
                    if (categories.Length > 0)
                    {
                        this.Add(categories[0]);
                        XmlConfigurationCategory newCategory = this[categories[0]];
                        if (categories.Length == 1)
                        {
                            return(newCategory);
                        }
                        else
                        {
                            keyOrPath = string.Join(XmlConfiguration.DefaultPathSeparator, categories, 1, categories.Length - 1);
                        }

                        return(newCategory.Categories[keyOrPath, createIfNotFound]);
                    }
                }
                return(null);
            }
        }
		public int Add(XmlConfigurationCategory category)
		{
			if (this.Contains(category))
				throw new ArgumentException("ElementName already exists. ElementName in collection: " + category.ElementName + " ElementName being added: " + category.ElementName);
				
			category.Parent = this;
			category.BeforeEdit += new XmlConfigurationElementCancelEventHandler(this.OnBeforeEdit);
			category.Changed += new XmlConfigurationElementEventHandler(this.OnChanged);			
			category.AfterEdit += new XmlConfigurationElementEventHandler(this.OnAfterEdit);
			category.EditCancelled += new XmlConfigurationElementEventHandler(this.OnEditCancelled);
			int index = base.InnerList.Add(category);
			this.OnChanged(this, new XmlConfigurationCategoryEventArgs(category, XmlConfigurationElementActions.Added));
			return index;
		}
Exemple #15
0
        public void Insert(int index, XmlConfigurationCategory category)
        {
            if (this.Contains(category))
            {
                throw new ArgumentException("ElementName already exists. ElementName in collection: " + category.ElementName + " ElementName being added: " + category.ElementName);
            }

            category.Parent         = this;
            category.BeforeEdit    += new XmlConfigurationElementCancelEventHandler(this.OnBeforeEdit);
            category.Changed       += new XmlConfigurationElementEventHandler(this.OnChanged);
            category.AfterEdit     += new XmlConfigurationElementEventHandler(this.OnAfterEdit);
            category.EditCancelled += new XmlConfigurationElementEventHandler(this.OnEditCancelled);
            base.InnerList.Insert(index, category);
            this.OnChanged(this, new XmlConfigurationCategoryEventArgs(category, XmlConfigurationElementActions.Added));
        }
Exemple #16
0
//		protected override XmlConfigurationElement GetElementToEdit()
//		{
//			XmlConfigurationCategory category = (XmlConfigurationCategory)this.Clone();
//			category.Parent = this.Parent;
//			return (XmlConfigurationElement)category;
//		}

        public override bool ApplyChanges(ISupportsEditing editableObject, SupportedEditingActions actions)
        {
            if (base.ApplyChanges(editableObject, actions))
            {
                XmlConfigurationCategory category = editableObject as XmlConfigurationCategory;
                if (category != null)
                {
                    if (_categories != null)
                    {
                        _categories.ApplyChanges((ISupportsEditing)category.Categories, actions);
                    }
                }
                return(true);
            }
            return(false);
        }
		public void Add(XmlConfigurationCategory[] categories)
		{
			if (categories == null)
				throw new ArgumentNullException("categories");			

			foreach(XmlConfigurationCategory category in categories) 
			{
				try 
				{
					this.Add(category);
				}
				catch(System.Exception systemException) 
				{
					System.Diagnostics.Trace.WriteLine(systemException);
				}
			}
		}
 public XmlConfigurationOptionCollectionTypeDescriptor(Hashtable table) : this()
 {
     foreach (DictionaryEntry entry in table)
     {
         try
         {
             XmlConfigurationCategory category = entry.Value as XmlConfigurationCategory;
             if (category != null)
             {
                 this.LoadOptions(category.Options);
             }
         }
         catch (System.Exception systemException)
         {
             System.Diagnostics.Trace.WriteLine(systemException);
         }
     }
 }
Exemple #19
0
        /// <summary>
        /// Clones this category collection
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            XmlConfigurationCategoryCollection clone = new XmlConfigurationCategoryCollection();

            clone.ResetBeforeEdit();
            clone.ResetChanged();
            clone.ResetAfterEdit();
            clone.ResetEditCancelled();
            clone.Parent = _parent;

            foreach (XmlConfigurationCategory category in base.InnerList)
            {
                XmlConfigurationCategory clonedCategory = (XmlConfigurationCategory)category.Clone();
                clonedCategory.Parent = clone;
                clone.Add(clonedCategory);
            }

            return(clone);
        }
Exemple #20
0
        /// <summary>
        /// Reads an XmlConfigurationCategoryCollection using the specified XPathNavigator
        /// </summary>
        /// <param name="navigator"></param>
        /// <returns></returns>
        private XmlConfigurationCategoryCollection ReadCategories(XPathNavigator navigator, XmlConfigurationCategoryCollection categories)
        {
            if (navigator.HasChildren)
            {
                if (navigator.MoveToFirstChild())
                {
                    // is this element a category node?
                    if (string.Compare(navigator.Name, @"Category", true) == 0)
                    {
                        // so read it
                        XmlConfigurationCategory category = new XmlConfigurationCategory();
                        category.BeginInit();
                        category.Parent = categories;

                        this.ReadCategory(navigator, category);

                        // and add it to the current collection of categories
                        categories.Add(category);
                        category.EndInit();
                    }
                }
            }

            while (navigator.MoveToNext())
            {
                // is this element a category node?
                if (string.Compare(navigator.Name, @"Category", true) == 0)
                {
                    // so read it
                    XmlConfigurationCategory category = new XmlConfigurationCategory();
                    category.BeginInit();
                    category.Parent = categories;

                    this.ReadCategory(navigator, category);

                    // and add it to the current collection of categories
                    categories.Add(category);
                    category.EndInit();
                }
            }

            return(categories);
        }
Exemple #21
0
        /// <summary>
        /// Selects the node's type descriptor into the property grid
        /// </summary>
        /// <param name="n"></param>
        private void SelectPropertyDescriptorForNodeIntoPropertyGrid(CategoryTreeNode n)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new SelectPropertyDescriptorForNodeIntoPropertyGridInvoker(this.SelectPropertyDescriptorForNodeIntoPropertyGrid), new object[] { n });
                return;
            }

            try
            {
                _propertyGrid.SelectedObject = null;
                _labelCategory.Text          = null;

                if (n != null)
                {
                    if (n.Categories.Count > 0)
                    {
                        XmlConfigurationOptionCollectionTypeDescriptor td = new XmlConfigurationOptionCollectionTypeDescriptor(n.Categories);
                        if (td != null)
                        {
                            _propertyGrid.SelectedObject = td;
                        }

                        foreach (DictionaryEntry entry in n.Categories)
                        {
                            XmlConfigurationCategory category = entry.Value as XmlConfigurationCategory;
                            if (category != null)
                            {
                                _labelCategory.Text = category.DisplayName;
                                break;
                            }
                        }
                    }
                }
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
            }
        }
Exemple #22
0
        public bool ApplyToSelf(ISupportsEditing editableObject, SupportedEditingActions actions)
        {
            XmlConfigurationCategoryCollection categories = editableObject as XmlConfigurationCategoryCollection;

            if (categories != null)
            {
                foreach (XmlConfigurationCategory category in categories)
                {
                    XmlConfigurationCategory myCategory = this[category.ElementName];
                    if (myCategory != null)
                    {
                        try
                        {
                            myCategory.ApplyToSelf((ISupportsEditing)category, actions);
                        }
                        catch (System.Exception systemException)
                        {
                            System.Diagnostics.Trace.WriteLine(systemException);
                        }
                    }
                }
            }
            return(true);
        }
Exemple #23
0
 /// <summary>
 /// Initializes a new instance of the XmlConfigurationCategory class
 /// </summary>
 public XmlConfigurationCategory(XmlConfigurationCategory category) : base((XmlConfigurationElement)category)
 {
     _options    = category.Options;
     _categories = category.Categories;
     _parent     = category.Parent;
 }
		public void Add(string elementName)
		{
			XmlConfigurationCategory category = null;

			if (!this.Contains(elementName))
			{
				category = new XmlConfigurationCategory(elementName);
				this.Add(category);
			}
		}
		/// <summary>
		/// Determines if the category is bound to the node
		/// </summary>
		/// <param name="category">The category to check bindings for</param>
		/// <returns></returns>
		public bool IsBoundToCategory(XmlConfigurationCategory category)
		{
			if (category != null)
				return _table.ContainsKey(category.Fullpath);			
			return false;
		}
Exemple #26
0
        /// <summary>
        /// Adds a category node into the treeview for the specified category
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="nodes"></param>
        /// <param name="category"></param>
        /// <returns></returns>
        private CategoryTreeNode AddNodeForCategory(TreeView tree, TreeNodeCollection nodes, XmlConfigurationCategory category)
        {
            if (this.InvokeRequired)
            {
                return(this.Invoke(new AddNodeForCategoryInvoker(this.AddNodeForCategory), new object[] { tree, nodes, category }) as CategoryTreeNode);
            }

            bool isRootCategory = (nodes == null);

            if (nodes == null)
            {
                if (tree != null)
                {
                    nodes = tree.Nodes;
                }
            }

            CategoryTreeNode n = new CategoryTreeNode(category.DisplayName);

            n.BindToCategory(category);
            nodes.Add(n);

            if (isRootCategory)
            {
                n.ImageIndex         = (int)CategoryImageIndexes.UnselectedWithSubCategories;
                n.SelectedImageIndex = (int)CategoryImageIndexes.SelectedWithSubCategories;
            }
            else
            {
                /// ok, off the root, now base images on whether the category has sub categories or not,
                /// and whether the category is selected
                if (category.Categories.Count > 0)
                {
                    n.ImageIndex         = (int)CategoryImageIndexes.UnselectedWithSubCategories;
                    n.SelectedImageIndex = (int)CategoryImageIndexes.SelectedWithSubCategories;
                }
                else
                {
                    n.ImageIndex         = (int)CategoryImageIndexes.NoImage;
                    n.SelectedImageIndex = (int)CategoryImageIndexes.SelectedWithoutSubCategories;
                }
            }

            return(n);
        }
		/// <summary>
		/// Adds a category node into the treeview for the specified category
		/// </summary>
		/// <param name="tree"></param>
		/// <param name="nodes"></param>
		/// <param name="category"></param>
		/// <returns></returns>
		private CategoryTreeNode AddNodeForCategory(TreeView tree, TreeNodeCollection nodes, XmlConfigurationCategory category)
		{
			if (this.InvokeRequired)
			{
				return this.Invoke(new AddNodeForCategoryInvoker(this.AddNodeForCategory), new object[] {tree, nodes, category}) as CategoryTreeNode;
			}

			bool isRootCategory = (nodes == null);

			if (nodes == null)
				if (tree != null)
					nodes = tree.Nodes;

			CategoryTreeNode n = new CategoryTreeNode(category.DisplayName);
			n.BindToCategory(category);
			nodes.Add(n);

			if (isRootCategory)
			{
				n.ImageIndex = (int)CategoryImageIndexes.UnselectedWithSubCategories;
				n.SelectedImageIndex = (int)CategoryImageIndexes.SelectedWithSubCategories;
			}
			else
			{
				/// ok, off the root, now base images on whether the category has sub categories or not, 
				/// and whether the category is selected
				if (category.Categories.Count > 0)
				{
					n.ImageIndex = (int)CategoryImageIndexes.UnselectedWithSubCategories;
					n.SelectedImageIndex = (int)CategoryImageIndexes.SelectedWithSubCategories;
				}
				else
				{
					n.ImageIndex = (int)CategoryImageIndexes.NoImage;
					n.SelectedImageIndex = (int)CategoryImageIndexes.SelectedWithoutSubCategories;
				}
			}

			return n;
		}
Exemple #28
0
        /// <summary>
        /// Reads an XmlConfigurationCategory using the specified XPathNavigator
        /// </summary>
        /// <param name="navigator"></param>
        /// <returns></returns>
        private XmlConfigurationCategory ReadCategory(XPathNavigator navigator, XmlConfigurationCategory category)
        {
            // break off a clone so that the starting cursor doesn't lose it's place
            XPathNavigator categoryNavigator = navigator.Clone();

            // does the cateogry have attributes, it should!
            if (categoryNavigator.HasAttributes)
            {
                // break off yet another clone to navigate the attributes of this element
                XPathNavigator attributesNavigator = categoryNavigator.Clone();
                if (attributesNavigator.MoveToFirstAttribute())
                {
                    category.ElementName = attributesNavigator.Value;

                    while (attributesNavigator.MoveToNextAttribute())
                    {
                        switch (attributesNavigator.Name)
                        {
                        case @"HasChanges":
                            category.HasChanges = XmlConvert.ToBoolean(attributesNavigator.Value);
                            break;

                        case @"Category":
                            category.Category = attributesNavigator.Value;
                            break;

                        case @"Description":
                            category.Description = attributesNavigator.Value;
                            break;

                        case @"DisplayName":
                            category.DisplayName = attributesNavigator.Value;
                            break;

                        case @"Hidden":
                            category.Hidden = XmlConvert.ToBoolean(attributesNavigator.Value);
                            break;
                        }
                        ;
                    }
                }
            }

            XmlConfigurationOption option          = null;
            XPathNavigator         optionNavigator = navigator.Clone();

            if (optionNavigator.HasChildren)
            {
                if (optionNavigator.MoveToFirstChild())
                {
                    option = new XmlConfigurationOption();
                    option.BeginInit();
                    if (this.ReadOption(optionNavigator, option) != null)
                    {
                        category.Options.Add(option);
                    }
                    option.EndInit();

                    while (optionNavigator.MoveToNext())
                    {
                        option = new XmlConfigurationOption();
                        option.BeginInit();
                        if (this.ReadOption(optionNavigator, option) != null)
                        {
                            category.Options.Add(option);
                        }
                        option.EndInit();
                    }
                }
            }

            if (navigator.HasChildren)
            {
                this.ReadCategories(categoryNavigator, category.Categories);
            }

            return(category);
        }
		/// <summary>
		/// Returns a clone of this category
		/// </summary>
		/// <returns></returns>
		public new XmlConfigurationCategory Clone()
		{						
			XmlConfigurationCategory clone = null;
			XmlConfigurationElement element = (XmlConfigurationElement)base.Clone();
			if (element != null)
			{
				clone = new XmlConfigurationCategory(element);
				clone.ResetBeforeEdit();
				clone.ResetChanged();
				clone.ResetAfterEdit();
				clone.ResetEditCancelled();
				
				if (_options != null)
					clone.Options = (XmlConfigurationOptionCollection)_options.Clone();

				if (_categories != null)
					clone.Categories = (XmlConfigurationCategoryCollection)_categories.Clone();
			}
			return clone;
		}
		/// <summary>
		/// Writes a category to the XmlDocument
		/// </summary>
		/// <param name="doc"></param>
		/// <param name="parent"></param>
		/// <param name="category"></param>
		/// <param name="alwaysPersist"></param>
		private void WriteCategory(XmlDocument doc, XmlElement parent, XmlConfigurationCategory category, bool alwaysPersist)
		{
			try
			{
				if (category.Persistent || alwaysPersist)
				{
					/// create an element for the category				
					XmlElement child = doc.CreateElement(@"Category");

					/// write the properties of this category
					child.SetAttribute(@"ElementName", category.ElementName);
					child.SetAttribute(@"HasChanges", XmlConvert.ToString(category.HasChanges));
					child.SetAttribute(@"Category", category.Category);
					child.SetAttribute(@"Description", category.Description);
					child.SetAttribute(@"DisplayName", category.DisplayName);
					child.SetAttribute(@"Hidden", XmlConvert.ToString(category.Hidden));
					
					/// append the child to our parent
					parent.AppendChild(child);

					/// write the options into the category
					this.WriteOptions(doc, child, category.Options, alwaysPersist);

					/// write recursively into the categories
					this.WriteCategories(doc, child, category.Categories, alwaysPersist);
				}
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
		}
		/// <summary>
		/// Finds an existing node for the specified category
		/// </summary>
		/// <param name="nodes"></param>
		/// <param name="category"></param>
		/// <returns></returns>
		private CategoryTreeNode FindNodeForCategory(TreeNodeCollection nodes, XmlConfigurationCategory category)
		{
			if (this.InvokeRequired)
			{
				return this.Invoke(new FindNodeForCategoryInvoker(this.FindNodeForCategory), new object[] {nodes, category}) as CategoryTreeNode;
			}

			if (nodes == null)
				// asume root
				nodes = _treeView.Nodes;

			if (nodes != null)
			{
				if (category != null)
				{
					foreach(CategoryTreeNode n in nodes)
					{
						//						if (n.IsBoundToCategory(category))
						//							return n;
						if (string.Compare(n.Text, category.DisplayName, true) == 0)
							return n;
					}
				}
			}
			return null;
		}
		public XmlConfigurationOptionCollectionTypeDescriptor(XmlConfigurationCategory category) : this()
		{
			this.LoadOptions(category.Options);
		}
 /// <summary>
 /// Initializes a new instance of the XmlConfigurationOptionEventArgs class
 /// </summary>
 /// <param name="option">The option being affected by this action</param>
 /// <param name="action">The action affecting this option</param>
 public XmlConfigurationCategoryEventArgs(XmlConfigurationCategory category, XmlConfigurationElementActions action) : base(category, action)
 {
 }
		/// <summary>
		/// Initializes a new instance of the XmlConfigurationCategory class
		/// </summary>
		public XmlConfigurationCategory(XmlConfigurationCategory category) : base((XmlConfigurationElement)category)
		{
			_options = category.Options;
			_categories = category.Categories;
			_parent = category.Parent;
		}
 public XmlConfigurationOptionCollectionTypeDescriptor(XmlConfigurationCategory category) : this()
 {
     this.LoadOptions(category.Options);
 }
		/// <summary>
		/// Reads an XmlConfigurationCategoryCollection using the specified XPathNavigator
		/// </summary>
		/// <param name="navigator"></param>
		/// <returns></returns>
		private XmlConfigurationCategoryCollection ReadCategories(XPathNavigator navigator, XmlConfigurationCategoryCollection categories)
		{			
			if (navigator.HasChildren)
			{
				if (navigator.MoveToFirstChild())
				{
					// is this element a category node?
					if (string.Compare(navigator.Name, @"Category", true) == 0)
					{
						// so read it
						XmlConfigurationCategory category = new XmlConfigurationCategory();
						category.BeginInit();
						category.Parent = categories;
						
						this.ReadCategory(navigator, category);						
						
						// and add it to the current collection of categories
						categories.Add(category);
						category.EndInit();
					}					
				}
			}

			while (navigator.MoveToNext())
			{	
				// is this element a category node?
				if (string.Compare(navigator.Name, @"Category", true) == 0)
				{
					// so read it
					XmlConfigurationCategory category = new XmlConfigurationCategory();
					category.BeginInit();
					category.Parent = categories;
					
					this.ReadCategory(navigator, category);					

					// and add it to the current collection of categories
					categories.Add(category);
					category.EndInit();
				}
			}
			
			return categories;
		}
		public void Remove(XmlConfigurationCategory category)
		{
			if (this.Contains(category))
			{											
				category.BeforeEdit -= new XmlConfigurationElementCancelEventHandler(this.OnBeforeEdit);
				category.Changed -= new XmlConfigurationElementEventHandler(this.OnChanged);			
				category.AfterEdit -= new XmlConfigurationElementEventHandler(this.OnAfterEdit);
				category.EditCancelled -= new XmlConfigurationElementEventHandler(this.OnEditCancelled);
				base.InnerList.Remove(category);
				this.OnChanged(this, new XmlConfigurationCategoryEventArgs(category, XmlConfigurationElementActions.Removed));
			}		
		}
		public bool Contains(XmlConfigurationCategory category)
		{
			foreach(XmlConfigurationCategory c in base.InnerList)
				if (c.ElementName == category.ElementName)
					return true;
			
			return false;
		}
		/// <summary>
		/// Reads an XmlConfigurationCategory using the specified XPathNavigator
		/// </summary>
		/// <param name="navigator"></param>
		/// <returns></returns>
		private XmlConfigurationCategory ReadCategory(XPathNavigator navigator, XmlConfigurationCategory category)
		{
			// break off a clone so that the starting cursor doesn't lose it's place
			XPathNavigator categoryNavigator = navigator.Clone();

			// does the cateogry have attributes, it should!
			if (categoryNavigator.HasAttributes)
			{
				// break off yet another clone to navigate the attributes of this element
				XPathNavigator attributesNavigator = categoryNavigator.Clone();
				if (attributesNavigator.MoveToFirstAttribute())
				{
					category.ElementName = attributesNavigator.Value;

					while(attributesNavigator.MoveToNextAttribute())
					{
						switch(attributesNavigator.Name)
						{
						case @"HasChanges":
							category.HasChanges = XmlConvert.ToBoolean(attributesNavigator.Value);
							break;
						case @"Category":
							category.Category = attributesNavigator.Value;
							break;
						case @"Description":
							category.Description = attributesNavigator.Value;
							break;
						case @"DisplayName":
							category.DisplayName = attributesNavigator.Value;
							break;
						case @"Hidden":
							category.Hidden = XmlConvert.ToBoolean(attributesNavigator.Value);
							break;
						};						
					}
				}
			}

			XmlConfigurationOption option = null;
			XPathNavigator optionNavigator = navigator.Clone();
			if (optionNavigator.HasChildren)
			{
				if (optionNavigator.MoveToFirstChild())
				{										
					option = new XmlConfigurationOption();
					option.BeginInit();
					if (this.ReadOption(optionNavigator, option) != null)
						category.Options.Add(option);											
					option.EndInit();
					
					while (optionNavigator.MoveToNext())
					{
						option = new XmlConfigurationOption();
						option.BeginInit();
						if (this.ReadOption(optionNavigator, option) != null)
							category.Options.Add(option);						
						option.EndInit();
					}					
				}
			}

			if (navigator.HasChildren)
			{
				this.ReadCategories(categoryNavigator, category.Categories);	
			}
						
			return category;
		}	
		/// <summary>
		/// Initializes a new instance of the XmlConfigurationOptionEventArgs class
		/// </summary>
		/// <param name="option">The option being affected by this action</param>
		/// <param name="action">The action affecting this option</param>
		public XmlConfigurationCategoryEventArgs(XmlConfigurationCategory category, XmlConfigurationElementActions action) : base(category, action)
		{
			
		}