DocumentOutline.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / AuthoringOM / Design / DocumentOutline.cs / 1305376 / DocumentOutline.cs

                            using System.Windows.Forms; 
using System.Windows.Forms.Design;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing; 
using System.Collections;
using System.Collections.Generic; 
using System; 
using System.Diagnostics;
 
namespace System.Workflow.ComponentModel.Design
{
 	/// 
	/// This class renders the document outline of the workflow being designed. It shows hierarchical 
	/// representation of the workflow model.
	///  
 	public class WorkflowOutline : UserControl 
	{
 		#region Fields 
 		private Hashtable			    activityToNodeMapping = new Hashtable();
		private	TreeView				treeView;
 		private IServiceProvider		serviceProvider;
		private	bool					isDirty = false; 
		#endregion
 
		#region Constructor and Dispose 
 		public WorkflowOutline(IServiceProvider serviceProvider)
		{ 
 			this.serviceProvider = serviceProvider;
 			Debug.Assert(serviceProvider != null, "Creating WorkflowOutline without service host");

			if (serviceProvider == null) 
 				throw new ArgumentNullException("serviceProvider");
 
			IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost; 
			if (designerHost == null)
				throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(IDesignerHost).FullName)); 

            // listen for loaded and unloaded events
            DesignSurface surface = GetService(typeof(DesignSurface)) as DesignSurface;
            if(surface == null) 
                throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(DesignSurface).FullName));
            surface.Loaded += new LoadedEventHandler(OnSurfaceLoaded); 
 
            IComponentChangeService componentChangeService = GetService(typeof(IComponentChangeService)) as IComponentChangeService;
            if (componentChangeService != null) 
            {
                componentChangeService.ComponentChanged += new ComponentChangedEventHandler(OnComponentChanged);
                componentChangeService.ComponentRename += new ComponentRenameEventHandler(OnComponentRename);
            } 

            WorkflowTheme.ThemeChanged += new EventHandler(OnThemeChanged); 
 
 			// Get an ISelectionService service
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService; 
 			if (selectionService != null)
 				selectionService.SelectionChanged += new System.EventHandler(this.OnSelectionChanged);

			IUIService uiService = GetService(typeof(IUIService)) as IUIService; 
 			if(uiService != null)
				this.Font = (Font)uiService.Styles["DialogFont"]; 
 
			// Set up treeview
			this.treeView = new TreeView(); 
 			this.treeView.Dock = DockStyle.Fill;
			this.treeView.HideSelection = false;
 			this.treeView.AfterSelect += new TreeViewEventHandler(this.OnTreeViewAfterSelect);
 			this.treeView.MouseDown += new MouseEventHandler(this.OnTreeViewMouseDown); 
			this.treeView.Font = this.Font;
 			this.treeView.ItemHeight = Math.Max(this.treeView.ItemHeight, 18); 
			this.Controls.Add(this.treeView); 
		}
 
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            { 
                this.IsDirty = false;
 
                WorkflowTheme.ThemeChanged -= new EventHandler(OnThemeChanged); 

				IComponentChangeService componentChangeService = GetService(typeof(IComponentChangeService)) as IComponentChangeService; 
                if (componentChangeService != null)
                {
                    componentChangeService.ComponentChanged -= new ComponentChangedEventHandler(OnComponentChanged);
                    componentChangeService.ComponentRename -= new ComponentRenameEventHandler(OnComponentRename); 
                }
 
                ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService; 
                if (selectionService != null)
                    selectionService.SelectionChanged -= new System.EventHandler(OnSelectionChanged); 

                DesignSurface surface = GetService(typeof(DesignSurface)) as DesignSurface;
                if (surface != null)
                    surface.Loaded -= new LoadedEventHandler(OnSurfaceLoaded); 

                this.serviceProvider = null; 
            } 

            base.Dispose(disposing); 
 		}
		#endregion

 		#region Public Methods 
 		//completly reloads the document outline tree
		private bool needsExpandAll = true; 
 		internal protected bool NeedsExpandAll 
		{
			get 
			{
 				return this.needsExpandAll;
			}
 			set 
 			{
				this.needsExpandAll = value; 
 			} 
		}
 
		internal protected TreeNode RootNode
		{
 			get
			{ 
 				if (this.treeView.Nodes.Count > 0)
 					return this.treeView.Nodes[0]; 
				else 
 					return null;
			} 
		}

		public void ReloadWorkflowOutline()
 		{ 
			OnBeginUpdate();
 
 			this.treeView.BeginUpdate(); 
 			try
			{ 
 				this.treeView.Nodes.Clear();
				this.activityToNodeMapping.Clear();

                IRootDesigner rootDesigner = ActivityDesigner.GetSafeRootDesigner(this.serviceProvider) as IRootDesigner; 
				if (rootDesigner != null && rootDesigner.Component != null && rootDesigner.Component is Activity)
					InsertDocOutlineNode(null, rootDesigner.Component as Activity, 0, true); 
 
 				if(NeedsExpandAll)
					this.treeView.ExpandAll(); 
 			}
 			finally
			{
 				this.treeView.EndUpdate(); 
			}
 
			IsDirty = false; 

			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService; 
 			if (selectionService != null && selectionService.PrimarySelection != null)
			{
                this.treeView.SelectedNode = this.activityToNodeMapping[selectionService.PrimarySelection] as WorkflowOutlineNode;
 				if (this.treeView.SelectedNode != null) 
 					this.treeView.SelectedNode.EnsureVisible();
			} 
 
 			OnEndUpdate();
		} 

		//refreshes color and icons of all document outline nodes
		public void RefreshWorkflowOutline()
 		{ 
			if (this.treeView.Nodes.Count > 0)
 				RefreshNode(this.treeView.Nodes[0] as WorkflowOutlineNode, true); 
 		} 
		#endregion
 
 		#region Protected Methods
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e); 

            ReloadWorkflowOutline(); 
        } 

		//gets called when the control is about to update the treeview 
		protected virtual void OnBeginUpdate()
		{
 		}
 
		//gets called when the control is done updating the treeview
 		protected virtual void OnEndUpdate() 
 		{ 
		}
 
 		protected virtual void OnRefreshNode(WorkflowOutlineNode node)
		{
            if (node == null)
                return; 

			Activity activity = node.Activity; 
			if (activity == null) 
 				return;
 
			//Update the designer image
 			int imageIndex = (this.treeView.ImageList != null) ? this.treeView.ImageList.Images.IndexOfKey(activity.GetType().FullName) : -1;
 			if (imageIndex == -1)
			{ 
 				ActivityDesigner activityDesigner = ActivityDesigner.GetDesigner(activity);
				if (activityDesigner != null) 
				{ 
					Bitmap activityImage = activityDesigner.StockImage as Bitmap;
 					if (activityImage != null) 
					{
 						if (this.treeView.ImageList == null)
 						{
							this.treeView.ImageList = new ImageList(); 
 							this.treeView.ImageList.ColorDepth = ColorDepth.Depth32Bit;
						} 
 
						this.treeView.ImageList.Images.Add(activity.GetType().FullName, activityImage);
						imageIndex = this.treeView.ImageList.Images.Count - 1; 
 					}
				}
 			}
 			node.ImageIndex = node.SelectedImageIndex = imageIndex; 

			//ask the node to update its color, text, etc 
 			node.RefreshNode(); 
		}
 
		//calls to create a new workflow node for a given activity
		//could return null which will indicate that we dont want to create a node for it
 		protected virtual WorkflowOutlineNode CreateNewNode(Activity activity)
		{ 
 			return new WorkflowOutlineNode(activity);
 		} 
 
		//gets called when user selected a node in the activity tree
 		protected virtual void OnNodeSelected(WorkflowOutlineNode node) 
		{
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
			if (selectionService != null && node != null && selectionService.PrimarySelection != node.Activity)
 			{ 
				// make the selected shape visible (note - the order is important, EnsureVisible will
 				// expand appropiate branches and set CAG into edit mode, which is crucial for 
 				// SetSelectedComponents to perform well) 
				WorkflowView workflowView = GetService(typeof(WorkflowView)) as WorkflowView;
 				if (workflowView != null) 
					workflowView.EnsureVisible(node.Activity);

				// select it
				selectionService.SetSelectedComponents(new object[] { node.Activity }, SelectionTypes.Replace); 
 			}
		} 
 
 		//gets called after adding a new not-null node to the activity tree
        protected virtual void OnNodeAdded(WorkflowOutlineNode node) 
        {
        }

 		//gets a tree node for the given activity 
        protected WorkflowOutlineNode GetNode(Activity activity)
        { 
            return this.activityToNodeMapping[activity] as WorkflowOutlineNode; 
        }
 
        protected void RefreshNode(WorkflowOutlineNode nodeToUpdate, bool refreshChildNodes)
        {
            this.treeView.BeginUpdate();
 
            Queue nodesQ = new Queue();
            nodesQ.Enqueue(nodeToUpdate); 
            while (nodesQ.Count > 0) 
            {
                WorkflowOutlineNode node = nodesQ.Dequeue(); 
                OnRefreshNode(node);

                if (refreshChildNodes)
                { 
                    foreach (TreeNode childNode in node.Nodes)
                    { 
                        WorkflowOutlineNode childOutlineNode = childNode as WorkflowOutlineNode; 
                        if (childOutlineNode != null)
                        { 
                            Activity childActivity = childOutlineNode.Activity;
                            if (childActivity != null)
                                nodesQ.Enqueue(childOutlineNode);
                        } 
                    }
                } 
 
                this.treeView.EndUpdate();
            } 
        }

		protected override object GetService(Type serviceType)
 		{ 
			object service = null;
			if (this.serviceProvider != null) 
				service = this.serviceProvider.GetService(serviceType); 
 			else
				service = base.GetService(serviceType); 
 			return service;
 		}
		#endregion
 
 		#region Protected Properties
		protected internal TreeView TreeView 
		{ 
			get
 			{ 
				return this.treeView;
 			}
 		}
 
		protected internal event TreeViewCancelEventHandler Expanding
 		{ 
			add 
			{
				this.treeView.BeforeExpand += value; 
 			}
			remove
 			{
 				this.treeView.BeforeExpand -= value; 
			}
 		} 
		#endregion 

		#region Private Properties 
		private bool IsDirty
 		{
			get
 			{ 
 				return this.isDirty;
			} 
 			set 
			{
				if (this.isDirty != value) 
				{
 					this.isDirty = value;
					if (value)
 						Application.Idle += new System.EventHandler(this.OnIdle); 
 					else
						Application.Idle -= new System.EventHandler(this.OnIdle); 
 				} 
			}
		} 
		#endregion

 		#region Private Methods
		private void InsertDocOutlineNode(WorkflowOutlineNode parentNode, Activity activity, int childIndex, bool addNestedActivities) 
 		{
 			if (this.activityToNodeMapping.Contains(activity)) 
				return; 

 			WorkflowOutlineNode newNode = CreateNewNode(activity); 
			if (newNode == null)
				return;

            RefreshNode(newNode, false); 
            this.activityToNodeMapping.Add(activity, newNode);
 
			if (addNestedActivities && activity is CompositeActivity) 
 			{
				foreach (Activity childActivity in ((CompositeActivity)activity).Activities) 
 					InsertDocOutlineNode(newNode, childActivity, newNode.Nodes.Count, addNestedActivities);
 			}

			if (parentNode != null) 
 				parentNode.Nodes.Insert(childIndex, newNode);
			else 
				this.treeView.Nodes.Add(newNode); 

            OnNodeAdded(newNode); 
		}

 		private void OnComponentChanged(object sender, ComponentChangedEventArgs e)
		{ 
 			ActivityCollectionChangeEventArgs changeEventArgs = e.OldValue as ActivityCollectionChangeEventArgs;
 			if (changeEventArgs != null) 
			{ 
                this.IsDirty = true;
 			} 
			else if (e.Member != null && e.Component is Activity)
			{
                WorkflowOutlineNode node = this.activityToNodeMapping[e.Component] as WorkflowOutlineNode;
				if (node != null && string.Equals(e.Member.Name, "Enabled", StringComparison.Ordinal)) 
 					RefreshNode(node, true);
            } 
		} 

        private void OnComponentRename(object sender, ComponentRenameEventArgs e) 
        {
            if (e.Component is Activity)
            {
 				// 
                WorkflowOutlineNode node = this.activityToNodeMapping[e.Component] as WorkflowOutlineNode;
                if (node != null) 
                    node.OnActivityRename(e.NewName); 
            }
        } 

 		private void OnIdle(object sender, EventArgs e)
		{
 			if (this.IsDirty && this.treeView.Visible) 
				ReloadWorkflowOutline();
		} 
 
		private void OnSelectionChanged(object sender, EventArgs e)
 		{ 
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
            if (selectionService != null && selectionService.PrimarySelection != null)
            {
                this.treeView.SelectedNode = this.activityToNodeMapping[selectionService.PrimarySelection] as WorkflowOutlineNode; 
                if(this.treeView.SelectedNode != null)
                    this.treeView.SelectedNode.EnsureVisible(); 
            } 
        }
 
        private void OnSurfaceLoaded(object sender, LoadedEventArgs e)
        {
 			ReloadWorkflowOutline();
        } 

 		private void OnTreeViewAfterSelect(object sender, TreeViewEventArgs e) 
		{ 
 			// Change the primary selection of the selection service
			WorkflowOutlineNode node = e.Node as WorkflowOutlineNode; 
			OnNodeSelected(node);
		}
 		private void OnTreeViewMouseDown(object sender, MouseEventArgs e)
		{ 
 			if (this.treeView.GetNodeAt(e.Location) != null)
 				this.treeView.SelectedNode = this.treeView.GetNodeAt(e.Location); 
		} 

 		private void OnThemeChanged(object sender, EventArgs e) 
		{
			if (this.treeView.Nodes.Count > 0)
			{
 				this.treeView.ImageList.Images.Clear(); 
				RefreshWorkflowOutline();
            } 
 		} 
 		#endregion
	} 

 	#region Class WorkflowOutlineNode
	/// 
	/// Class representing the node in document outline 
	/// 
 	public class WorkflowOutlineNode : TreeNode 
	{ 
        private Activity activity;
 
        public WorkflowOutlineNode(Activity activity)
 			: base()
 		{
            if (activity == null) 
                throw new ArgumentNullException("activity");
 
			this.activity = activity; 
            this.Name = activity.Name;
 		} 

		public Activity Activity
		{
			get 
 			{
				return this.activity; 
 			} 
 		}
 
		//gets called to update node properties (like color, text)
 		public virtual void RefreshNode()
		{
			Activity activity = this.Activity; 
			if (activity == null)
 				return; 
 
			//Update the enabled color
 			this.ForeColor = (!activity.Enabled || ActivityDesigner.IsCommentedActivity(activity)) ? WorkflowTheme.CurrentTheme.AmbientTheme.CommentIndicatorColor : SystemColors.WindowText; 
            this.Text = activity.Name;
 		}

        public virtual void OnActivityRename(string newName) 
        {
            this.Text = newName; 
        } 
	}
 	#endregion 

}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System.Windows.Forms; 
using System.Windows.Forms.Design;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing; 
using System.Collections;
using System.Collections.Generic; 
using System; 
using System.Diagnostics;
 
namespace System.Workflow.ComponentModel.Design
{
 	/// 
	/// This class renders the document outline of the workflow being designed. It shows hierarchical 
	/// representation of the workflow model.
	///  
 	public class WorkflowOutline : UserControl 
	{
 		#region Fields 
 		private Hashtable			    activityToNodeMapping = new Hashtable();
		private	TreeView				treeView;
 		private IServiceProvider		serviceProvider;
		private	bool					isDirty = false; 
		#endregion
 
		#region Constructor and Dispose 
 		public WorkflowOutline(IServiceProvider serviceProvider)
		{ 
 			this.serviceProvider = serviceProvider;
 			Debug.Assert(serviceProvider != null, "Creating WorkflowOutline without service host");

			if (serviceProvider == null) 
 				throw new ArgumentNullException("serviceProvider");
 
			IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost; 
			if (designerHost == null)
				throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(IDesignerHost).FullName)); 

            // listen for loaded and unloaded events
            DesignSurface surface = GetService(typeof(DesignSurface)) as DesignSurface;
            if(surface == null) 
                throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(DesignSurface).FullName));
            surface.Loaded += new LoadedEventHandler(OnSurfaceLoaded); 
 
            IComponentChangeService componentChangeService = GetService(typeof(IComponentChangeService)) as IComponentChangeService;
            if (componentChangeService != null) 
            {
                componentChangeService.ComponentChanged += new ComponentChangedEventHandler(OnComponentChanged);
                componentChangeService.ComponentRename += new ComponentRenameEventHandler(OnComponentRename);
            } 

            WorkflowTheme.ThemeChanged += new EventHandler(OnThemeChanged); 
 
 			// Get an ISelectionService service
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService; 
 			if (selectionService != null)
 				selectionService.SelectionChanged += new System.EventHandler(this.OnSelectionChanged);

			IUIService uiService = GetService(typeof(IUIService)) as IUIService; 
 			if(uiService != null)
				this.Font = (Font)uiService.Styles["DialogFont"]; 
 
			// Set up treeview
			this.treeView = new TreeView(); 
 			this.treeView.Dock = DockStyle.Fill;
			this.treeView.HideSelection = false;
 			this.treeView.AfterSelect += new TreeViewEventHandler(this.OnTreeViewAfterSelect);
 			this.treeView.MouseDown += new MouseEventHandler(this.OnTreeViewMouseDown); 
			this.treeView.Font = this.Font;
 			this.treeView.ItemHeight = Math.Max(this.treeView.ItemHeight, 18); 
			this.Controls.Add(this.treeView); 
		}
 
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            { 
                this.IsDirty = false;
 
                WorkflowTheme.ThemeChanged -= new EventHandler(OnThemeChanged); 

				IComponentChangeService componentChangeService = GetService(typeof(IComponentChangeService)) as IComponentChangeService; 
                if (componentChangeService != null)
                {
                    componentChangeService.ComponentChanged -= new ComponentChangedEventHandler(OnComponentChanged);
                    componentChangeService.ComponentRename -= new ComponentRenameEventHandler(OnComponentRename); 
                }
 
                ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService; 
                if (selectionService != null)
                    selectionService.SelectionChanged -= new System.EventHandler(OnSelectionChanged); 

                DesignSurface surface = GetService(typeof(DesignSurface)) as DesignSurface;
                if (surface != null)
                    surface.Loaded -= new LoadedEventHandler(OnSurfaceLoaded); 

                this.serviceProvider = null; 
            } 

            base.Dispose(disposing); 
 		}
		#endregion

 		#region Public Methods 
 		//completly reloads the document outline tree
		private bool needsExpandAll = true; 
 		internal protected bool NeedsExpandAll 
		{
			get 
			{
 				return this.needsExpandAll;
			}
 			set 
 			{
				this.needsExpandAll = value; 
 			} 
		}
 
		internal protected TreeNode RootNode
		{
 			get
			{ 
 				if (this.treeView.Nodes.Count > 0)
 					return this.treeView.Nodes[0]; 
				else 
 					return null;
			} 
		}

		public void ReloadWorkflowOutline()
 		{ 
			OnBeginUpdate();
 
 			this.treeView.BeginUpdate(); 
 			try
			{ 
 				this.treeView.Nodes.Clear();
				this.activityToNodeMapping.Clear();

                IRootDesigner rootDesigner = ActivityDesigner.GetSafeRootDesigner(this.serviceProvider) as IRootDesigner; 
				if (rootDesigner != null && rootDesigner.Component != null && rootDesigner.Component is Activity)
					InsertDocOutlineNode(null, rootDesigner.Component as Activity, 0, true); 
 
 				if(NeedsExpandAll)
					this.treeView.ExpandAll(); 
 			}
 			finally
			{
 				this.treeView.EndUpdate(); 
			}
 
			IsDirty = false; 

			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService; 
 			if (selectionService != null && selectionService.PrimarySelection != null)
			{
                this.treeView.SelectedNode = this.activityToNodeMapping[selectionService.PrimarySelection] as WorkflowOutlineNode;
 				if (this.treeView.SelectedNode != null) 
 					this.treeView.SelectedNode.EnsureVisible();
			} 
 
 			OnEndUpdate();
		} 

		//refreshes color and icons of all document outline nodes
		public void RefreshWorkflowOutline()
 		{ 
			if (this.treeView.Nodes.Count > 0)
 				RefreshNode(this.treeView.Nodes[0] as WorkflowOutlineNode, true); 
 		} 
		#endregion
 
 		#region Protected Methods
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e); 

            ReloadWorkflowOutline(); 
        } 

		//gets called when the control is about to update the treeview 
		protected virtual void OnBeginUpdate()
		{
 		}
 
		//gets called when the control is done updating the treeview
 		protected virtual void OnEndUpdate() 
 		{ 
		}
 
 		protected virtual void OnRefreshNode(WorkflowOutlineNode node)
		{
            if (node == null)
                return; 

			Activity activity = node.Activity; 
			if (activity == null) 
 				return;
 
			//Update the designer image
 			int imageIndex = (this.treeView.ImageList != null) ? this.treeView.ImageList.Images.IndexOfKey(activity.GetType().FullName) : -1;
 			if (imageIndex == -1)
			{ 
 				ActivityDesigner activityDesigner = ActivityDesigner.GetDesigner(activity);
				if (activityDesigner != null) 
				{ 
					Bitmap activityImage = activityDesigner.StockImage as Bitmap;
 					if (activityImage != null) 
					{
 						if (this.treeView.ImageList == null)
 						{
							this.treeView.ImageList = new ImageList(); 
 							this.treeView.ImageList.ColorDepth = ColorDepth.Depth32Bit;
						} 
 
						this.treeView.ImageList.Images.Add(activity.GetType().FullName, activityImage);
						imageIndex = this.treeView.ImageList.Images.Count - 1; 
 					}
				}
 			}
 			node.ImageIndex = node.SelectedImageIndex = imageIndex; 

			//ask the node to update its color, text, etc 
 			node.RefreshNode(); 
		}
 
		//calls to create a new workflow node for a given activity
		//could return null which will indicate that we dont want to create a node for it
 		protected virtual WorkflowOutlineNode CreateNewNode(Activity activity)
		{ 
 			return new WorkflowOutlineNode(activity);
 		} 
 
		//gets called when user selected a node in the activity tree
 		protected virtual void OnNodeSelected(WorkflowOutlineNode node) 
		{
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
			if (selectionService != null && node != null && selectionService.PrimarySelection != node.Activity)
 			{ 
				// make the selected shape visible (note - the order is important, EnsureVisible will
 				// expand appropiate branches and set CAG into edit mode, which is crucial for 
 				// SetSelectedComponents to perform well) 
				WorkflowView workflowView = GetService(typeof(WorkflowView)) as WorkflowView;
 				if (workflowView != null) 
					workflowView.EnsureVisible(node.Activity);

				// select it
				selectionService.SetSelectedComponents(new object[] { node.Activity }, SelectionTypes.Replace); 
 			}
		} 
 
 		//gets called after adding a new not-null node to the activity tree
        protected virtual void OnNodeAdded(WorkflowOutlineNode node) 
        {
        }

 		//gets a tree node for the given activity 
        protected WorkflowOutlineNode GetNode(Activity activity)
        { 
            return this.activityToNodeMapping[activity] as WorkflowOutlineNode; 
        }
 
        protected void RefreshNode(WorkflowOutlineNode nodeToUpdate, bool refreshChildNodes)
        {
            this.treeView.BeginUpdate();
 
            Queue nodesQ = new Queue();
            nodesQ.Enqueue(nodeToUpdate); 
            while (nodesQ.Count > 0) 
            {
                WorkflowOutlineNode node = nodesQ.Dequeue(); 
                OnRefreshNode(node);

                if (refreshChildNodes)
                { 
                    foreach (TreeNode childNode in node.Nodes)
                    { 
                        WorkflowOutlineNode childOutlineNode = childNode as WorkflowOutlineNode; 
                        if (childOutlineNode != null)
                        { 
                            Activity childActivity = childOutlineNode.Activity;
                            if (childActivity != null)
                                nodesQ.Enqueue(childOutlineNode);
                        } 
                    }
                } 
 
                this.treeView.EndUpdate();
            } 
        }

		protected override object GetService(Type serviceType)
 		{ 
			object service = null;
			if (this.serviceProvider != null) 
				service = this.serviceProvider.GetService(serviceType); 
 			else
				service = base.GetService(serviceType); 
 			return service;
 		}
		#endregion
 
 		#region Protected Properties
		protected internal TreeView TreeView 
		{ 
			get
 			{ 
				return this.treeView;
 			}
 		}
 
		protected internal event TreeViewCancelEventHandler Expanding
 		{ 
			add 
			{
				this.treeView.BeforeExpand += value; 
 			}
			remove
 			{
 				this.treeView.BeforeExpand -= value; 
			}
 		} 
		#endregion 

		#region Private Properties 
		private bool IsDirty
 		{
			get
 			{ 
 				return this.isDirty;
			} 
 			set 
			{
				if (this.isDirty != value) 
				{
 					this.isDirty = value;
					if (value)
 						Application.Idle += new System.EventHandler(this.OnIdle); 
 					else
						Application.Idle -= new System.EventHandler(this.OnIdle); 
 				} 
			}
		} 
		#endregion

 		#region Private Methods
		private void InsertDocOutlineNode(WorkflowOutlineNode parentNode, Activity activity, int childIndex, bool addNestedActivities) 
 		{
 			if (this.activityToNodeMapping.Contains(activity)) 
				return; 

 			WorkflowOutlineNode newNode = CreateNewNode(activity); 
			if (newNode == null)
				return;

            RefreshNode(newNode, false); 
            this.activityToNodeMapping.Add(activity, newNode);
 
			if (addNestedActivities && activity is CompositeActivity) 
 			{
				foreach (Activity childActivity in ((CompositeActivity)activity).Activities) 
 					InsertDocOutlineNode(newNode, childActivity, newNode.Nodes.Count, addNestedActivities);
 			}

			if (parentNode != null) 
 				parentNode.Nodes.Insert(childIndex, newNode);
			else 
				this.treeView.Nodes.Add(newNode); 

            OnNodeAdded(newNode); 
		}

 		private void OnComponentChanged(object sender, ComponentChangedEventArgs e)
		{ 
 			ActivityCollectionChangeEventArgs changeEventArgs = e.OldValue as ActivityCollectionChangeEventArgs;
 			if (changeEventArgs != null) 
			{ 
                this.IsDirty = true;
 			} 
			else if (e.Member != null && e.Component is Activity)
			{
                WorkflowOutlineNode node = this.activityToNodeMapping[e.Component] as WorkflowOutlineNode;
				if (node != null && string.Equals(e.Member.Name, "Enabled", StringComparison.Ordinal)) 
 					RefreshNode(node, true);
            } 
		} 

        private void OnComponentRename(object sender, ComponentRenameEventArgs e) 
        {
            if (e.Component is Activity)
            {
 				// 
                WorkflowOutlineNode node = this.activityToNodeMapping[e.Component] as WorkflowOutlineNode;
                if (node != null) 
                    node.OnActivityRename(e.NewName); 
            }
        } 

 		private void OnIdle(object sender, EventArgs e)
		{
 			if (this.IsDirty && this.treeView.Visible) 
				ReloadWorkflowOutline();
		} 
 
		private void OnSelectionChanged(object sender, EventArgs e)
 		{ 
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
            if (selectionService != null && selectionService.PrimarySelection != null)
            {
                this.treeView.SelectedNode = this.activityToNodeMapping[selectionService.PrimarySelection] as WorkflowOutlineNode; 
                if(this.treeView.SelectedNode != null)
                    this.treeView.SelectedNode.EnsureVisible(); 
            } 
        }
 
        private void OnSurfaceLoaded(object sender, LoadedEventArgs e)
        {
 			ReloadWorkflowOutline();
        } 

 		private void OnTreeViewAfterSelect(object sender, TreeViewEventArgs e) 
		{ 
 			// Change the primary selection of the selection service
			WorkflowOutlineNode node = e.Node as WorkflowOutlineNode; 
			OnNodeSelected(node);
		}
 		private void OnTreeViewMouseDown(object sender, MouseEventArgs e)
		{ 
 			if (this.treeView.GetNodeAt(e.Location) != null)
 				this.treeView.SelectedNode = this.treeView.GetNodeAt(e.Location); 
		} 

 		private void OnThemeChanged(object sender, EventArgs e) 
		{
			if (this.treeView.Nodes.Count > 0)
			{
 				this.treeView.ImageList.Images.Clear(); 
				RefreshWorkflowOutline();
            } 
 		} 
 		#endregion
	} 

 	#region Class WorkflowOutlineNode
	/// 
	/// Class representing the node in document outline 
	/// 
 	public class WorkflowOutlineNode : TreeNode 
	{ 
        private Activity activity;
 
        public WorkflowOutlineNode(Activity activity)
 			: base()
 		{
            if (activity == null) 
                throw new ArgumentNullException("activity");
 
			this.activity = activity; 
            this.Name = activity.Name;
 		} 

		public Activity Activity
		{
			get 
 			{
				return this.activity; 
 			} 
 		}
 
		//gets called to update node properties (like color, text)
 		public virtual void RefreshNode()
		{
			Activity activity = this.Activity; 
			if (activity == null)
 				return; 
 
			//Update the enabled color
 			this.ForeColor = (!activity.Enabled || ActivityDesigner.IsCommentedActivity(activity)) ? WorkflowTheme.CurrentTheme.AmbientTheme.CommentIndicatorColor : SystemColors.WindowText; 
            this.Text = activity.Name;
 		}

        public virtual void OnActivityRename(string newName) 
        {
            this.Text = newName; 
        } 
	}
 	#endregion 

}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK