ActivityDesigner.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

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

                            #pragma warning disable 1634, 1691 
namespace System.Workflow.ComponentModel.Design
{
    using System;
    using System.IO; 
    using System.Drawing;
    using System.CodeDom; 
    using System.Diagnostics; 
    using System.Collections;
    using System.Collections.Generic; 
    using System.Windows.Forms;
    using System.ComponentModel;
    using System.Globalization;
    using System.Drawing.Design; 
    using System.Drawing.Imaging;
    using System.Drawing.Drawing2D; 
    using System.Windows.Forms.Design; 
    using System.ComponentModel.Design;
    using System.Collections.Specialized; 
    using System.ComponentModel.Design.Serialization;
    using System.Workflow.ComponentModel.Compiler;
    using System.Workflow.ComponentModel.Serialization;
    using System.Collections.ObjectModel; 
    using System.Reflection;
    using System.Workflow.ComponentModel.Design; 
    using System.Runtime.Serialization.Formatters.Binary; 

    // 

    #region ActivityDesigner Class
    /// 
    /// ActivityDesigner provides a simple designer which allows user to visually design activities in the design mode. 
    /// ActivityDesigner provides simple mechanism using which the activities can participate in rendering the Workflow.
    /// ActivityDesigner enables the user to customize layouting, drawing associated with the activity. 
    /// It also enables the user to extend the meta data associated with the activity. 
    /// 
    [ActivityDesignerTheme(typeof(ActivityDesignerTheme))] 
    [SRCategory("ActivityDesigners", "System.Workflow.ComponentModel.Design.DesignerResources")]
    [DesignerSerializer(typeof(ActivityDesignerLayoutSerializer), typeof(WorkflowMarkupSerializer))]
    [ToolboxItemFilter("Microsoft.Workflow.VSDesigner", ToolboxItemFilterType.Require)]
    [ToolboxItemFilter("System.Workflow.ComponentModel.Design.ActivitySet", ToolboxItemFilterType.Custom)] 
    public class ActivityDesigner : IDisposable,
                                    IDesignerFilter, 
                                    IDesigner, 
                                    IToolboxUser,
                                    IPersistUIState, 
                                    IWorkflowDesignerMessageSink,
                                    IWorkflowRootDesigner,
                                    IConnectableDesigner
    { 
        #region Fields
        //Members which determine the linesize of text in ActivityDesigner 
        private const int MaximumCharsPerLine = 8; 
        private const int MaximumTextLines = 2;
        private const int MaximumIdentifierLength = 25; 
        private const int MaximumDescriptionLength = 80;
        private const uint FrameworkVersion_3_5 = 0x00030005;
        private const uint FrameworkVersion_3_0 = 0x00030000;
 
        //ActivityDesigner Related Members
        private Activity activity; 
        private ActivityDesignerAccessibleObject accessibilityObject; 
        private ActivityDesignerVerbCollection designerVerbs;
        private List designerActions; 

        [Flags]
        internal enum DrawingStates { Valid = 0, InvalidPosition = 1, InvalidSize = 2, InvalidDraw = 4 };
        private DrawingStates drawingState = DrawingStates.Valid; 

        private Point location = Point.Empty; 
        private Size size = Size.Empty; 
        private Image image;
        private string text = String.Empty; 
        private Size textSize = Size.Empty;
        private bool smartTagVisible = false;
        private SmartTag smartTag = new SmartTag();
        private bool isVisible = true; 
        private string rulesText = null;
 
        //RootDesigner Related Members 
        private CompositeActivityDesigner invokingDesigner;
        private WorkflowView workflowView; 
        #endregion

        #region Construction and Destruction
        public ActivityDesigner() 
        {
        } 
 
        ~ActivityDesigner()
        { 
            Dispose(false);
        }
        #endregion
 
        #region Properties
 
        #region Public Properties 
        /// 
        /// Gets activity being designed by the designer. 
        /// 
        public Activity Activity
        {
            get 
            {
                return this.activity; 
            } 
        }
 
        /// 
        /// Gets the parent designer of existing designer
        /// 
        public CompositeActivityDesigner ParentDesigner 
        {
            get 
            { 
                CompositeActivityDesigner parentDesigner = null;
                IWorkflowRootDesigner rootDesigner = this as IWorkflowRootDesigner; 
                if (rootDesigner != null && IsRootDesigner)
                    parentDesigner = rootDesigner.InvokingDesigner;
                else if (Activity != null && Activity.Parent != null)
                    parentDesigner = ActivityDesigner.GetDesigner(Activity.Parent) as CompositeActivityDesigner; 
                return parentDesigner;
            } 
        } 

        ///  
        /// Gets value indicating if the activity associated with the designer is selected.
        /// 
        public bool IsSelected
        { 
            get
            { 
                ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService; 
                return (selectionService != null && selectionService.GetComponentSelected(Activity));
            } 
        }

        /// 
        /// Gets value indicating if the activity associated with the designer is primary selection. 
        /// 
        public bool IsPrimarySelection 
        { 
            get
            { 
                ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
                return (selectionService != null && selectionService.PrimarySelection == Activity);
            }
        } 

        ///  
        /// Gets the accessibility object associated with the designer 
        /// 
        public virtual AccessibleObject AccessibilityObject 
        {
            get
            {
                if (this.accessibilityObject == null) 
                    this.accessibilityObject = new ActivityDesignerAccessibleObject(this);
                return this.accessibilityObject; 
            } 
        }
 
        /// 
        /// Gets the value indicating if a designer is visible on the workflow.
        /// Designer is said to be invisible if the parent of the designer is collapsed or in cases where
        /// designer is not shown on the workflow. 
        /// 
        public virtual bool IsVisible 
        { 
            get
            { 
                return this.isVisible;
            }
        }
 
        /// 
        /// Get value indicating if the activity associated with the designer can be modified. 
        /// This property also controls the position of the designer in the workflow. 
        /// It is used in edit operations such as drag drop, delete, cut/copy/paste etc.
        ///  
        public bool IsLocked
        {
            get
            { 
                if (Helpers.IsActivityLocked(Activity))
                    return true; 
 
                if (DrawingState != DrawingStates.Valid)
                    return true; 

                WorkflowDesignerLoader loader = GetService(typeof(WorkflowDesignerLoader)) as WorkflowDesignerLoader;
                if (loader != null && loader.InDebugMode)
                    return true; 

                IWorkflowRootDesigner rootDesigner = ActivityDesigner.GetSafeRootDesigner(Activity.Site) as IWorkflowRootDesigner; 
                if (rootDesigner != null && rootDesigner.InvokingDesigner != null) 
                    return true;
 
                return false;
            }
        }
 
        /// 
        /// Gets or Sets the location of the designer in logical coordinates. 
        ///  
        public virtual Point Location
        { 
            get
            {
                return this.location;
            } 

            set 
            { 
                if (ParentDesigner is FreeformActivityDesigner)
                    value = DesignerHelpers.SnapToGrid(value); 

                if (this.location != value)
                    this.location = value;
            } 
        }
 
        ///  
        /// Gets or Sets the size of the designer.
        ///  
        public virtual Size Size
        {
            get
            { 
                return this.size;
            } 
 
            set
            { 
                value.Width = Math.Max(value.Width, MinimumSize.Width);
                value.Height = Math.Max(value.Height, MinimumSize.Height);

                if (this.size != value) 
                    this.size = value;
            } 
        } 

        ///  
        /// Get the minimum size of the designer
        /// 
        public virtual Size MinimumSize
        { 
            get
            { 
                return DesignerTheme.Size; 
            }
        } 

        /// 
        /// Get value for enclosing rectangle of the designer in logical coordinates.
        ///  
        public Rectangle Bounds
        { 
            get 
            {
                //Bounds contain designer rectangle + the selection area 
                return new Rectangle(Location, Size);
            }
        }
 
        /// 
        /// Gets the image associated with the designer. 
        ///  
        public virtual Image Image
        { 
            get
            {
                return this.image;
            } 
            protected set
            { 
                this.image = value; 
                PerformLayout();
            } 
        }

        /// 
        /// Gets the text associated with the designer. 
        /// 
        public virtual string Text 
        { 
            get
            { 
                return this.text;
            }
            protected set
            { 
                if (value == null || value.Length == 0 || this.text == value)
                    return; 
 
                this.text = value;
                PerformLayout(); 
            }
        }

        ///  
        /// Gets the current theme to be used for the designer
        ///  
        public ActivityDesignerTheme DesignerTheme 
        {
            get 
            {
                return WorkflowTheme.CurrentTheme.GetDesignerTheme(this);
            }
        } 

        ///  
        /// Gets the value indicating if the designer is root designer. 
        /// 
        public bool IsRootDesigner 
        {
            get
            {
                bool isRootDesigner = false; 
                IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
                if (designerHost != null) 
                    isRootDesigner = (designerHost.RootComponent == Activity); 
                return isRootDesigner;
            } 
        }
        #endregion

        #region Protected Properties 
        /// 
        /// Returns the WorkflowView containing the designer 
        ///  
        protected internal WorkflowView ParentView
        { 
            get
            {
                return GetService(typeof(WorkflowView)) as WorkflowView;
            } 
        }
 
        ///  
        /// Gets the collection of verbs to be associated with the designer.
        /// The verbs are shown on context menu and the top level workflow menu. 
        /// 
        protected virtual ActivityDesignerVerbCollection Verbs
        {
            get 
            {
                if (this.designerVerbs == null) 
                { 
                    this.designerVerbs = new ActivityDesignerVerbCollection();
                    if (!IsLocked) 
                        this.designerVerbs.Add(new ActivityDesignerVerb(this, DesignerVerbGroup.General, DR.GetString(DR.GenerateEventHandlers), new EventHandler(OnGenerateEventHandler), new EventHandler(OnGenerateEventHandlerStatusUpdate)));

                    // Add the item to choose an activity datasource
                    WorkflowDesignerLoader loader = GetService(typeof(WorkflowDesignerLoader)) as WorkflowDesignerLoader; 
                    if (this.Activity.Parent != null)
                        this.designerVerbs.Add(new ActivityDesignerVerb(this, DesignerVerbGroup.General, DR.GetString(DR.PromoteBindings), new EventHandler(OnPromoteBindings), new EventHandler(OnPromoteBindingsStatusUpdate))); 
 
                    this.designerVerbs.Add(new ActivityDesignerVerb(this, DesignerVerbGroup.General, DR.GetString(DR.BindSelectedProperty), new EventHandler(OnBindProperty), new EventHandler(OnBindPropertyStatusUpdate)));
 
                    ActivityDesignerVerb designerVerb = new ActivityDesignerVerb(this, DesignerVerbGroup.General, DR.GetString(DR.MoveLeftDesc), new EventHandler(OnMoveBranch), new EventHandler(OnStatusMoveBranch));
                    designerVerb.Properties[DesignerUserDataKeys.MoveBranchKey] = true;
                    this.designerVerbs.Add(designerVerb);
 
                    designerVerb = new ActivityDesignerVerb(this, DesignerVerbGroup.General, DR.GetString(DR.MoveRightDesc), new EventHandler(OnMoveBranch), new EventHandler(OnStatusMoveBranch));
                    designerVerb.Properties[DesignerUserDataKeys.MoveBranchKey] = false; 
                    this.designerVerbs.Add(designerVerb); 

                    foreach (ActivityDesignerVerb smartVerb in SmartTagVerbs) 
                        this.designerVerbs.Add(smartVerb);
                }

                return this.designerVerbs; 
            }
        } 
 
        /// 
        /// Gets or sets the value indicating if smarttag should be shown. 
        /// 
        protected virtual bool ShowSmartTag
        {
            get 
            {
                return false; 
            } 
        }
 
        /// 
        /// Gets the array of actions which the designer wants to associated with the smarttag.
        /// 
        protected virtual ReadOnlyCollection SmartTagVerbs 
        {
            get 
            { 
                return new List().AsReadOnly();
            } 
        }

        /// 
        /// Gets the Rectangle where the smarttag needs to be displayed 
        /// 
        protected virtual Rectangle SmartTagRectangle 
        { 
            get
            { 
                Rectangle smartTagRectangle = Rectangle.Empty;

                Rectangle imageRectangle = ImageRectangle;
                if (!imageRectangle.Size.IsEmpty) 
                {
                    smartTagRectangle = imageRectangle; 
                } 

                return smartTagRectangle; 
            }
        }

        ///  
        /// Gets the array of actions associated with the configuration errors.
        ///  
        protected internal virtual ReadOnlyCollection DesignerActions 
        {
            get 
            {
                if (this.designerActions == null)
                {
                    this.designerActions = new List(); 

                    Activity activity = Activity; 
                    if (activity != null) 
                    {
                        bool isNestedInComment = ActivityDesigner.IsCommentedActivity(activity); 

                        WorkflowDesignerLoader loader = GetService(typeof(WorkflowDesignerLoader)) as WorkflowDesignerLoader;
                        bool debugMode = (loader != null && loader.InDebugMode);
 
                        if (activity.Enabled && !isNestedInComment && !IsLocked && activity.Site != null && !debugMode)
                        { 
                            ValidationErrorCollection validationErrors = new ValidationErrorCollection(); 
                            try
                            { 
                                ValidationManager validationManager = new ValidationManager(Activity.Site, false);
                                using (WorkflowCompilationContext.CreateScope(validationManager))
                                {
                                    Activity rootActivity = Helpers.GetRootActivity(this.Activity); 
                                    foreach (Validator validator in validationManager.GetValidators(activity.GetType()))
                                        validationErrors.AddRange(validator.Validate(validationManager, activity)); 
                                } 
                            }
                            catch 
                            {
                                Debug.WriteLine("Validate call failed");
                            }
 
                            //Populate the validation errors
                            if (validationErrors.Count > 0) 
                            { 
                                for (int i = 0; i < validationErrors.Count; i++)
                                { 
                                    ValidationError error = validationErrors[i] as ValidationError;
                                    Debug.Assert(error != null, "someone inserted a null or no 'ValidationError' type error in errors collection.");
                                    if (error != null && !error.IsWarning)
                                    { 
                                        DesignerAction designerAction = new DesignerAction(this, i, error.ErrorText, AmbientTheme.ConfigErrorImage);
                                        designerAction.PropertyName = error.PropertyName; 
                                        foreach (DictionaryEntry entry in error.UserData) 
                                            designerAction.UserData[entry.Key] = entry.Value;
                                        this.designerActions.Add(designerAction); 
                                    }
                                }
                            }
                        } 
                    }
                } 
 
                return this.designerActions.AsReadOnly();
            } 
        }

        /// 
        /// Gets the array of glyphs with which to adorn the designer. 
        /// 
        protected internal virtual ActivityDesignerGlyphCollection Glyphs 
        { 
            get
            { 
                ActivityDesignerGlyphCollection glyphs = new ActivityDesignerGlyphCollection();

                if (IsSelected)
                { 
                    if (IsPrimarySelection)
                        glyphs.Add(PrimarySelectionGlyph.Default); 
                    else 
                        glyphs.Add(NonPrimarySelectionGlyph.Default);
                } 

                bool isNestedInComment = ActivityDesigner.IsCommentedActivity(Activity);

                WorkflowDesignerLoader loader = GetService(typeof(WorkflowDesignerLoader)) as WorkflowDesignerLoader; 
                bool debugMode = (loader != null && loader.InDebugMode);
 
                if (WorkflowTheme.CurrentTheme.AmbientTheme.ShowConfigErrors && 
                    Activity.Enabled && !isNestedInComment && !debugMode &&
                    DesignerActions.Count > 0) 
                    glyphs.Add(ConfigErrorGlyph.Default);

                //Add comment glyph only for ctop level comments
                if (!Activity.Enabled && !isNestedInComment) 
                    glyphs.Add(CommentGlyph.Default);
 
                // 
                if (Helpers.IsActivityLocked(Activity))
                    glyphs.Add(LockedActivityGlyph.Default); 

                if (SmartTagVisible && ShowSmartTag)
                    glyphs.Add(this.smartTag);
 
                return glyphs;
            } 
        } 

        ///  
        /// Gets the value of text rectangle in logical coordinates.
        /// 
        protected virtual Rectangle TextRectangle
        { 
            get
            { 
                //BY DEFAULT THE TEXT IS ALIGNED TO THE BOTTOM 
                if (String.IsNullOrEmpty(Text))
                    return Rectangle.Empty; 

                AmbientTheme ambientTheme = WorkflowTheme.CurrentTheme.AmbientTheme;
                ActivityDesignerTheme designerTheme = DesignerTheme;
 
                Rectangle bounds = Bounds;
                Rectangle textRectangle = Rectangle.Empty; 
                textRectangle.X = bounds.Left + ambientTheme.Margin.Width; 
                textRectangle.X += (Image != null) ? designerTheme.ImageSize.Width + ambientTheme.Margin.Width : 0;
                textRectangle.Y = bounds.Top + (bounds.Height - this.textSize.Height) / 2; 
                textRectangle.Size = this.textSize;
                return textRectangle;
            }
        } 

        ///  
        /// Gets the value for enclosing bounds image associated with the designer in logical coordinates. 
        /// 
        protected virtual Rectangle ImageRectangle 
        {
            get
            {
                //BY DEFAULT THE ICON RECTANGLE IS ALIGNED TO TOP / CENTER 
                if (Image == null)
                    return Rectangle.Empty; 
 
                AmbientTheme ambientTheme = WorkflowTheme.CurrentTheme.AmbientTheme;
                ActivityDesignerTheme designerTheme = DesignerTheme; 

                Rectangle bounds = Bounds;
                Rectangle imageRectangle = Rectangle.Empty;
                imageRectangle.X = bounds.Left + WorkflowTheme.CurrentTheme.AmbientTheme.Margin.Width; 
                imageRectangle.Y = bounds.Top + (bounds.Height - DesignerTheme.ImageSize.Height) / 2;
                imageRectangle.Size = designerTheme.ImageSize; 
                return imageRectangle; 
            }
        } 

        protected virtual CompositeActivityDesigner InvokingDesigner
        {
            get 
            {
                return this.invokingDesigner; 
            } 

            set 
            {
                this.invokingDesigner = value;
            }
        } 

        protected virtual ReadOnlyCollection MessageFilters 
        { 
            get
            { 
                List stockFilters = new List();
                stockFilters.Add(new ConnectionManager());
                stockFilters.Add(new ResizingMessageFilter());
                stockFilters.Add(new DynamicActionMessageFilter()); 
                stockFilters.Add(new AutoScrollingMessageFilter());
                stockFilters.Add(new AutoExpandingMessageFilter()); 
                stockFilters.Add(new DragSelectionMessageFilter()); 
                stockFilters.Add(new FreeFormDragDropManager());
                return stockFilters.AsReadOnly(); 
            }
        }

        ///  
        /// Get if the designer is resizable using the rubberbanding when dropped in FreeformDesigner
        ///  
        protected internal virtual bool EnableVisualResizing 
        {
            get 
            {
                return false;
            }
        } 
        #endregion
 
        #region Private Properties 

        #region Properties used during serialization only 
        //Note that the following property is used by ActivityDesignerLayoutSerializer to
        //associate a designer with activity
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 
        internal string Name
        { 
            get 
            {
                return ((Activity != null) ? Activity.Name : null); 
            }

            set
            { 
            }
        } 
        #endregion 

        internal virtual bool SupportsLayoutPersistence 
        {
            get
            {
                bool supportsLayoutPersistence = false; 
                IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
                if (designerHost != null) 
                { 
                    foreach (IComponent component in designerHost.Container.Components)
                    { 
                        Activity activity = component as Activity;
                        if (activity != null && ActivityDesigner.GetDesigner(activity) is FreeformActivityDesigner)
                        {
                            supportsLayoutPersistence = true; 
                            break;
                        } 
                    } 
                }
                return supportsLayoutPersistence; 
            }
        }

        internal virtual WorkflowLayout SupportedLayout 
        {
            get 
            { 
                return new ActivityRootLayout(Activity.Site);
            } 
        }

        internal SmartTag DesignerSmartTag
        { 
            get
            { 
                return this.smartTag; 
            }
        } 

        internal DrawingStates DrawingState
        {
            get 
            {
                return this.drawingState; 
            } 

            set 
            {
                this.drawingState = value;
            }
        } 

        internal Image StockImage 
        { 
            get
            { 
                if (Activity == null)
                    return null;

                Image designerImage = DesignerTheme.DesignerImage; 
                if (designerImage == null)
                    designerImage = ActivityToolboxItem.GetToolboxImage(Activity.GetType()); 
 
                return designerImage;
            } 
        }

        internal virtual bool SmartTagVisible
        { 
            get
            { 
                if (ShowSmartTag && this.smartTag.ActiveDesigner != null) 
                    return true;
 
                return this.smartTagVisible;
            }

            set 
            {
                if (this.smartTagVisible == value) 
                    return; 

                this.smartTagVisible = value; 
                OnSmartTagVisibilityChanged(this.smartTagVisible);
            }
        }
 
        private PropertyDescriptor[] EventHandlerProperties
        { 
            get 
            {
                List propertyDescriptors = new List(); 

                //Site can be null when we are dragging item from the toolbox onto the design surface
                if (Activity.Site != null)
                { 
                    foreach (PropertyDescriptor propertyDescriptor in PropertyDescriptorFilter.GetPropertiesForEvents(Activity.Site, Activity))
                        propertyDescriptors.Add(propertyDescriptor); 
                } 

                return propertyDescriptors.ToArray(); 
            }
        }

        private PropertyDescriptor[] BindableProperties 
        {
            get 
            { 
                List propertyDescriptors = new List();
 
                if (!Helpers.IsActivityLocked(Activity))
                {
                    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(Activity, new Attribute[] { new BrowsableAttribute(true) });
                    if (properties != null) 
                    {
                        foreach (PropertyDescriptor propDesc in properties) 
                        { 
                            if (propDesc.Converter is ActivityBindTypeConverter)
                                propertyDescriptors.Add(propDesc); 
                        }
                    }
                }
                return propertyDescriptors.ToArray(); 
            }
        } 
 
        private string InfoTipTitle
        { 
            get
            {
                string title = String.Empty;
                if (Activity.Parent == null) 
                {
                    title = Activity.GetType().Name; 
                } 
                else
                { 
                    string activityName = (Activity.Name.Length > MaximumIdentifierLength) ? Activity.Name.Substring(0, MaximumIdentifierLength) + "..." : Activity.Name;
                    title = DR.GetString(DR.InfoTipTitle, Activity.GetType().Name, activityName);
                }
                return title; 
            }
        } 
 
        private string InfoTipText
        { 
            get
            {
                string tipText = (!String.IsNullOrEmpty(Activity.Description)) ? Activity.Description : ActivityDesigner.GetActivityDescription(Activity.GetType());
                tipText = (tipText.Length > MaximumDescriptionLength) ? tipText.Substring(0, MaximumDescriptionLength) + "..." : tipText; 
                if (RulesText.Length > 0)
                    tipText += "\n\n" + RulesText; 
 
                return tipText;
            } 
        }

        private string RulesText
        { 
            get
            { 
                if (this.rulesText == null) 
                {
                    this.rulesText = String.Empty; 

                    IDictionary rules = DesignerHelpers.GetDeclarativeRules(Activity);
                    if (rules.Count > 0)
                    { 
                        this.rulesText = DR.GetString(DR.Rules);
 
                        int maxRulesLength = 3 * (MaximumIdentifierLength + MaximumDescriptionLength); 
                        foreach (KeyValuePair rule in rules)
                        { 
                            this.rulesText += "\n";

                            string ruleName = rule.Key as string;
                            ruleName = (ruleName.Length > MaximumIdentifierLength) ? ruleName.Substring(0, MaximumIdentifierLength) + "..." : ruleName; 

                            string ruleDescription = rule.Value as string; 
                            ruleDescription = (ruleDescription.Length > MaximumDescriptionLength) ? ruleDescription.Substring(0, MaximumDescriptionLength) + "..." : ruleDescription; 
                            if (ruleDescription.Length == 0)
                                ruleDescription = DR.GetString(DR.Empty); 

                            this.rulesText += String.Format(CultureInfo.CurrentCulture, "{0}: {1}", ruleName, ruleDescription);
                            if (this.rulesText.Length > maxRulesLength)
                                break; 
                        }
 
                        if (this.rulesText.Length > maxRulesLength) 
                            this.rulesText += "\n\n" + DR.GetString(DR.More);
                    } 
                }

                return this.rulesText;
            } 
        }
 
        private void OnMoveBranch(object sender, EventArgs e) 
        {
            ActivityDesignerVerb moveBranchVerb = sender as ActivityDesignerVerb; 
            if (moveBranchVerb != null)
                ParallelActivityDesigner.MoveDesigners(this, (bool)moveBranchVerb.Properties[DesignerUserDataKeys.MoveBranchKey]);
        }
 
        private void OnStatusMoveBranch(object sender, EventArgs e)
        { 
            ActivityDesignerVerb moveBranchVerb = sender as ActivityDesignerVerb; 
            if (moveBranchVerb == null)
                return; 

            bool enableVerb = false;

            CompositeActivityDesigner parentDesigner = ParentDesigner; 
            if (!IsLocked && parentDesigner != null)
            { 
                List activities = new List(); 

                foreach (Activity containedActivity in ((CompositeActivity)parentDesigner.Activity).Activities) 
                {
                    if (!Helpers.IsAlternateFlowActivity(containedActivity))
                        activities.Add(containedActivity); ;
                } 

                //ActivityCollection activities = ((CompositeActivity)parentDesigner.Activity).Activities; 
                bool moveleft = (bool)moveBranchVerb.Properties[DesignerUserDataKeys.MoveBranchKey]; 
                int index = activities.IndexOf(Activity as Activity);
                // "Move Left" should be disabled if the immediate proceeding branch is locked. 
                int proceedingLockedIndex = (index > 0) ? index - 1 : -1;
                enableVerb = (index >= 0 && ((moveleft && index > 0 && (index - proceedingLockedIndex) > 0) || (!moveleft && index < activities.Count - 1)));
            }
 
            moveBranchVerb.Visible = (parentDesigner is ParallelActivityDesigner || parentDesigner is ActivityPreviewDesigner && !Helpers.IsAlternateFlowActivity(Activity));
            moveBranchVerb.Enabled = enableVerb; 
        } 

        #endregion 

        #endregion

        #region Methods 

        #region Public Static Methods 
        public static ActivityDesigner GetRootDesigner(IServiceProvider serviceProvider) 
        {
            if (serviceProvider == null) 
                throw new ArgumentNullException("serviceProvider");

            IDesignerHost designerHost = serviceProvider.GetService(typeof(IDesignerHost)) as IDesignerHost;
            return (designerHost != null) ? GetDesigner(designerHost.RootComponent as Activity) as ActivityDesigner : null; 
        }
 
        ///  
        /// Returns if the Activity is commented or is inside commented activity
        ///  
        /// 
        /// 
        public static bool IsCommentedActivity(Activity activity)
        { 
            if (activity == null)
                throw new ArgumentNullException("activity"); 
 
            bool isNestedComment = false;
            CompositeActivity parentActivity = activity.Parent; 
            while (parentActivity != null && !isNestedComment)
            {
                isNestedComment = (parentActivity != null && !parentActivity.Enabled);
                parentActivity = parentActivity.Parent; 
            }
 
            return isNestedComment; 
        }
        #endregion 

        #region Public Methods
        /// 
        /// Returns if a CompositeActivity can be set as parent of activity associated with designer. 
        /// This method is called in case of insertion operation such as Drag-Drop or Paste.
        ///  
        /// CompositeActivity which can be potentially set as parent. 
        /// True if the CompositeActivity can be set as parent of activity associated with designer, false otherwise.
        public virtual bool CanBeParentedTo(CompositeActivityDesigner parentActivityDesigner) 
        {
            if (parentActivityDesigner == null)
                throw new ArgumentNullException("parentActivityDesigner");
 
            return true;
        } 
 
        /// 
        /// Allows detection of the area hit on the designer. 
        /// 
        /// Point to test in logical coordinates.
        /// Information indicating where the hit happened
        public virtual HitTestInfo HitTest(Point point) 
        {
            HitTestInfo hitInfo = HitTestInfo.Nowhere; 
            if (ParentDesigner is FreeformActivityDesigner || 
                (ParentDesigner == null && this is FreeformActivityDesigner))
            { 
                //Check if the hit is on connection
                ReadOnlyCollection connectionPoints = GetConnectionPoints(DesignerEdges.All);
                for (int j = 0; j < connectionPoints.Count; j++)
                { 
                    if (connectionPoints[j].Bounds.Contains(point))
                    { 
                        hitInfo = new ConnectionPointHitTestInfo(connectionPoints[j]); 
                        break;
                    } 
                }
            }

            Rectangle bounds = Bounds; 
            if (bounds.Contains(point) && hitInfo == HitTestInfo.Nowhere)
            { 
                HitTestLocations flags = (bounds.Contains(point)) ? HitTestLocations.Designer : HitTestLocations.None; 

                Rectangle hitRectangle = new Rectangle(bounds.Left, bounds.Top, bounds.Left - bounds.Left, bounds.Height); 
                flags |= (hitRectangle.Contains(point)) ? HitTestLocations.Left : flags;

                hitRectangle = new Rectangle(bounds.Left, bounds.Top, bounds.Width, bounds.Height - bounds.Height);
                flags |= (hitRectangle.Contains(point)) ? HitTestLocations.Top : flags; 

                hitRectangle = new Rectangle(bounds.Right, bounds.Top, bounds.Width - bounds.Width, bounds.Height); 
                flags |= (hitRectangle.Contains(point)) ? HitTestLocations.Right : flags; 

                hitRectangle = new Rectangle(bounds.Left, bounds.Bottom, bounds.Width, bounds.Bottom - bounds.Bottom); 
                flags |= (hitRectangle.Contains(point)) ? HitTestLocations.Bottom : flags;

                hitInfo = new HitTestInfo(this, flags);
            } 

            return hitInfo; 
        } 

        ///  
        /// Brings designer in viewable area
        /// 
        public void EnsureVisible()
        { 
            WorkflowView parentView = ParentView;
            if (parentView != null) 
                parentView.EnsureVisible(Activity); 
        }
 
        /// 
        /// Get the points used to connect the designer. Points are in logical coordinates.
        /// 
        public virtual ReadOnlyCollection GetConnectionPoints(DesignerEdges edges) 
        {
            List connectionPoints = new List(); 
 
            if ((edges & DesignerEdges.Left) > 0)
            { 
                for (int i = 0; i < GetConnections(DesignerEdges.Left).Count; i++)
                    connectionPoints.Add(new ConnectionPoint(this, DesignerEdges.Left, i));
            }
 
            if ((edges & DesignerEdges.Right) > 0)
            { 
                for (int i = 0; i < GetConnections(DesignerEdges.Right).Count; i++) 
                    connectionPoints.Add(new ConnectionPoint(this, DesignerEdges.Right, i));
            } 

            if ((edges & DesignerEdges.Top) > 0)
            {
                for (int i = 0; i < GetConnections(DesignerEdges.Top).Count; i++) 
                    connectionPoints.Add(new ConnectionPoint(this, DesignerEdges.Top, i));
            } 
 
            if ((edges & DesignerEdges.Bottom) > 0)
            { 
                for (int i = 0; i < GetConnections(DesignerEdges.Bottom).Count; i++)
                    connectionPoints.Add(new ConnectionPoint(this, DesignerEdges.Bottom, i));
            }
 
            return connectionPoints.AsReadOnly();
        } 
 
        /// 
        /// Invalidates the entire workflow designer 
        /// 
        public void Invalidate()
        {
            WorkflowView parentView = ParentView; 
            if (parentView != null)
            { 
                parentView.InvalidateLogicalRectangle(Bounds); 

                GlyphManager glyphManager = GetService(typeof(IDesignerGlyphProviderService)) as GlyphManager; 
                if (glyphManager != null)
                {
                    foreach (DesignerGlyph glyph in glyphManager.GetDesignerGlyphs(this))
                        parentView.InvalidateLogicalRectangle(glyph.GetBounds(this, false)); 
                }
            } 
        } 

        ///  
        /// Invalidates specified rectangle on the designer
        /// 
        /// Rectangle to invalidate
        public void Invalidate(Rectangle rectangle) 
        {
            WorkflowView parentView = ParentView; 
            if (parentView != null) 
            {
                rectangle = Rectangle.Intersect(Bounds, rectangle); 
                parentView.InvalidateLogicalRectangle(rectangle);
            }
        }
 
        /// 
        /// Get image of the activity designer on specified graphics 
        ///  
        /// Graphics objects to draw image
        /// Image which is drawn 
        public Image GetPreviewImage(Graphics compatibleGraphics)
        {
            if (compatibleGraphics == null)
                throw new ArgumentNullException("compatibleGraphics"); 

            //Update the layout 
            if (Activity.Site == null) 
            {
                ((IWorkflowDesignerMessageSink)this).OnLayoutSize(compatibleGraphics); 
                ((IWorkflowDesignerMessageSink)this).OnLayoutPosition(compatibleGraphics);
            }

            AmbientTheme ambientTheme = WorkflowTheme.CurrentTheme.AmbientTheme; 
            Bitmap designerImage = new Bitmap(Size.Width + (4 * ambientTheme.Margin.Width), Size.Height + (4 * ambientTheme.Margin.Height), PixelFormat.Format32bppArgb);
 
            GlyphManager glyphManager = (Activity != null && Activity.Site != null) ? GetService(typeof(IDesignerGlyphProviderService)) as GlyphManager : null; 

            using (Graphics graphics = Graphics.FromImage(designerImage)) 
            using (Brush transparentBrush = new SolidBrush(Color.FromArgb(0, 255, 0, 255)))
            {
                graphics.FillRectangle(transparentBrush, 0, 0, designerImage.Width, designerImage.Height);
                graphics.TranslateTransform(-Location.X + 2 * ambientTheme.Margin.Width, -Location.Y + 2 * ambientTheme.Margin.Height); 

                //We need to go thru nested designers to generate the preview 
                Rectangle bounds = Bounds; 
                Rectangle viewPort = new Rectangle(bounds.Location, new Size(bounds.Width + 1, bounds.Height + 1));
                Queue designers = new Queue(); 
                designers.Enqueue(this);
                while (designers.Count > 0)
                {
                    ActivityDesigner designer = designers.Dequeue(); 
                    designer.OnPaint(new ActivityDesignerPaintEventArgs(graphics, designer.Bounds, viewPort, designer.DesignerTheme));
 
                    ActivityDesignerGlyphCollection glyphs = (glyphManager != null) ? glyphManager.GetDesignerGlyphs(designer) : Glyphs; 
                    foreach (DesignerGlyph glyph in glyphs)
                    { 
                        //
                        if (!(glyph is SelectionGlyph))
                            glyph.Draw(graphics, designer);
                    } 

                    CompositeActivityDesigner compositeDesigner = designer as CompositeActivityDesigner; 
                    if (compositeDesigner != null) 
                    {
                        foreach (ActivityDesigner containedDesigner in compositeDesigner.ContainedDesigners) 
                        {
                            if (containedDesigner != null && compositeDesigner.Expanded && compositeDesigner.IsContainedDesignerVisible(containedDesigner))
                                designers.Enqueue(containedDesigner);
                        } 
                    }
                } 
            } 

            return designerImage; 
        }
        #endregion

        #region Protected Methods 
        /// 
        /// Initializes the designer with associated activity. 
        ///  
        /// Activity with which the designer needs to be initialized.
        protected virtual void Initialize(Activity activity) 
        {
            if (activity == null)
                throw new ArgumentNullException("activity");
 
            if (IsRootDesigner)
            { 
                // Listen for the completed load.  When finished, we need to select the form.  We don' 
                // want to do it before we're done, however, or else the dimensions of the selection rectangle
                // could be off because during load, change events are not fired. 
                IDesignerHost designerHost = (IDesignerHost)GetService(typeof(IDesignerHost));
                if (designerHost != null && InvokingDesigner == null)
                    designerHost.LoadComplete += new EventHandler(OnLoadComplete);
 
                IComponentChangeService changeService = GetService(typeof(IComponentChangeService)) as IComponentChangeService;
                if (changeService != null) 
                { 
                    changeService.ComponentChanged += new ComponentChangedEventHandler(OnComponentChanged);
                    changeService.ComponentRename += new ComponentRenameEventHandler(OnComponentRenamed); 
                }
            }

            this.Text = (!String.IsNullOrEmpty(activity.Name)) ? activity.Name : activity.GetType().Name; 
            this.Image = StockImage;
 
            //We need to update the Verbs when the designer first loads up 
            RefreshDesignerVerbs();
 
            if (IsLocked)
                DesignerHelpers.MakePropertiesReadOnly(activity.Site, activity);
        }
 
        /// 
        /// Disposes the resources held by the designer. 
        ///  
        /// True if the designer is being disposed, false if the designer is being finalized.
        protected virtual void Dispose(bool disposing) 
        {
            if (disposing)
            {
                if (IsRootDesigner) 
                {
                    if (this.workflowView != null) 
                    { 
                        this.workflowView.Dispose();
                        this.workflowView = null; 
                    }

                    IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
                    if (designerHost != null && InvokingDesigner == null && Activity == designerHost.RootComponent) 
                        designerHost.LoadComplete -= new EventHandler(OnLoadComplete);
 
                    IComponentChangeService changeService = GetService(typeof(IComponentChangeService)) as IComponentChangeService; 
                    if (changeService != null)
                    { 
                        changeService.ComponentChanged -= new ComponentChangedEventHandler(OnComponentChanged);
                        changeService.ComponentRename -= new ComponentRenameEventHandler(OnComponentRenamed);
                    }
                } 
            }
        } 
 
        /// 
        /// Get the points used to connect the designer. Points are in logical coordinates. 
        /// 
        protected internal virtual ReadOnlyCollection GetConnections(DesignerEdges edges)
        {
            Rectangle bounds = Bounds; 

            List connections = new List(); 
            if ((edges & DesignerEdges.Left) > 0) 
                connections.Add(new Point(bounds.Left, bounds.Top + bounds.Height / 2));
 
            if ((edges & DesignerEdges.Top) > 0)
                connections.Add(new Point(bounds.Left + bounds.Width / 2, bounds.Top));

            if ((edges & DesignerEdges.Right) > 0) 
                connections.Add(new Point(bounds.Right, bounds.Top + bounds.Height / 2));
 
            if ((edges & DesignerEdges.Bottom) > 0) 
                connections.Add(new Point(bounds.Left + bounds.Width / 2, bounds.Bottom));
 
            return connections.AsReadOnly();
        }

        ///  
        /// Perform default UI action associated with the designer.
        /// Example: Emit method associated with default event in code beside file on double click. 
        ///  
        protected virtual void DoDefaultAction()
        { 
            if (IsLocked)
                return;

            DefaultEventAttribute defaultEventAttribute = TypeDescriptor.GetAttributes(Activity)[typeof(DefaultEventAttribute)] as DefaultEventAttribute; 
            if (defaultEventAttribute == null || defaultEventAttribute.Name == null || defaultEventAttribute.Name.Length == 0)
                return; 
 
            ActivityBindPropertyDescriptor defaultPropEvent = TypeDescriptor.GetProperties(Activity)[defaultEventAttribute.Name] as ActivityBindPropertyDescriptor;
            if (defaultPropEvent != null) 
            {
                object value = defaultPropEvent.GetValue(Activity);
                if (!(value is ActivityBind))
                { 
                    IEventBindingService eventBindingService = (IEventBindingService)GetService(typeof(IEventBindingService));
                    if (eventBindingService != null) 
                    { 
                        EventDescriptor eventDesc = eventBindingService.GetEvent(defaultPropEvent.RealPropertyDescriptor);
                        if (eventDesc != null) 
                        {
                            string handler = defaultPropEvent.RealPropertyDescriptor.GetValue(Activity) as string;
                            if (string.IsNullOrEmpty(handler))
                                handler = DesignerHelpers.CreateUniqueMethodName(Activity, eventDesc.Name, eventDesc.EventType); 

                            defaultPropEvent.SetValue(Activity, handler); 
                            eventBindingService.ShowCode(Activity, eventDesc); 
                        }
                    } 
                }
            }
        }
 
        /// 
        /// When overridden in a derived class, allows a designer to add items to the set of attributes that it exposes through a TypeDescriptor. 
        ///  
        /// The Attribute objects for the class of the activity. The keys in the dictionary of attributes are the TypeID values of the attributes.
        protected virtual void PreFilterAttributes(IDictionary attributes) 
        {
            if (attributes == null)
                throw new ArgumentNullException("attributes");
        } 

        ///  
        /// When overridden in a derived class, allows a designer to add items to the set of properties that it exposes through a TypeDescriptor. 
        /// 
        /// The PropertyDescriptor objects that represent the properties of the class of the activity. The keys in the dictionary of properties are property names. 
        protected virtual void PreFilterProperties(IDictionary properties)
        {
            if (properties == null)
                throw new ArgumentNullException("properties"); 
        }
 
        ///  
        /// When overridden in a derived class, allows a designer to add items to the set of events that it exposes through a TypeDescriptor.
        ///  
        /// The EventDescriptor objects that represent the events of the class of the activity. The keys in the dictionary of events are event names.
        protected virtual void PreFilterEvents(IDictionary events)
        {
            if (events == null) 
                throw new ArgumentNullException("events");
        } 
 
        /// 
        /// When overridden in a derived class, allows a designer to change or remove items from the set of attributes that it exposes through a TypeDescriptor. 
        /// 
        /// The Attribute objects for the class of the activity. The keys in the dictionary of attributes are the TypeID values of the attributes.
        protected virtual void PostFilterAttributes(IDictionary attributes)
        { 
            if (attributes == null)
                throw new ArgumentNullException("attributes"); 
        } 

        ///  
        /// When overridden in a derived class, allows a designer to change or remove items from the set of properties that it exposes through a TypeDescriptor.
        /// 
        /// The PropertyDescriptor objects that represent the properties of the class of the activity. The keys in the dictionary of properties are property names.
        protected virtual void PostFilterProperties(IDictionary properties) 
        {
            if (properties == null) 
                throw new ArgumentNullException("properties"); 

            // NOTE: I have to do this work around, reason being IExtenderProvider.CanExtend is not used 
            // to determine whether the properties should be extended or not. So I am fixing it
            // on designer part
            StringCollection removedProperties = new StringCollection();
            foreach (DictionaryEntry entry in properties) 
            {
                PropertyDescriptor prop = entry.Value as PropertyDescriptor; 
                ExtenderProvidedPropertyAttribute eppa = prop.Attributes[typeof(ExtenderProvidedPropertyAttribute)] as ExtenderProvidedPropertyAttribute; 
                if (eppa != null && eppa.Provider != null && !eppa.Provider.CanExtend(Activity))
                    removedProperties.Add(entry.Key as string); 
            }

            foreach (string removedPropoerty in removedProperties)
                properties.Remove(removedPropoerty); 

            PropertyDescriptorFilter.FilterProperties(Activity.Site, Activity, properties); 
        } 

        ///  
        /// When overridden in a derived class, allows a designer to change or remove items from the set of events that it exposes through a TypeDescriptor.
        /// 
        /// The EventDescriptor objects that represent the events of the class of the activity. The keys in the dictionary of events are event names.
        protected virtual void PostFilterEvents(IDictionary events) 
        {
            if (events == null) 
                throw new ArgumentNullException("events"); 
        }
 
        /// 
        /// Attempts to retrieve the specified type of service from the designer's activity's design mode site.
        /// 
        /// The type of service to request. 
        /// An object implementing the requested service, or a null reference (Nothing in Visual Basic) if the service cannot be resolved.
        protected object GetService(Type serviceType) 
        { 
            if (serviceType == null)
                throw new ArgumentNullException("serviceType"); 

            if (this.activity != null && this.activity.Site != null)
                return this.activity.Site.GetService(serviceType);
            else 
                return null;
        } 
 
        /// 
        /// Called when the users begins to drag mouse on the designer. 
        /// 
        /// Point where the drag started in logical coordinates
        /// MouseEventArgs containing event data.
        protected virtual void OnMouseDragBegin(Point initialDragPoint, MouseEventArgs e) 
        {
            if (e == null) 
                throw new ArgumentNullException("e"); 
        }
 
        /// 
        /// Called when the users drags mouse over the designer.
        /// 
        /// MouseEventArgs containing event data. 
        protected virtual void OnMouseDragMove(MouseEventArgs e)
        { 
            if (e == null) 
                throw new ArgumentNullException("e");
        } 

        /// 
        /// Called when the mouse drag ends.
        ///  
        protected virtual void OnMouseDragEnd()
        { 
        } 

        ///  
        /// Called when the mouse cursor enters the designer bounds.
        /// 
        /// MouseEventArgs containing event data.
        protected virtual void OnMouseEnter(MouseEventArgs e) 
        {
            if (e == null) 
                throw new ArgumentNullException("e"); 

            if (IsVisible) 
            {
                if (ShowSmartTag)
                    SmartTagVisible = true;
 
                ShowInfoTip(InfoTipTitle, InfoTipText);
            } 
        } 

        ///  
        /// Called when the mouse button is clicked when mouse cursor is in designer bounds.
        /// 
        /// MouseEventArgs containing event data.
        protected virtual void OnMouseDown(MouseEventArgs e) 
        {
            if (e == null) 
                throw new ArgumentNullException("e"); 
        }
 
        /// 
        /// Called when the mouse cursor is moving in designer bounds.
        /// 
        /// MouseEventArgs containing event data. 
        protected virtual void OnMouseMove(MouseEventArgs e)
        { 
            if (e == null) 
                throw new ArgumentNullException("e");
 
            if (IsVisible)
                ShowInfoTip(InfoTipTitle, InfoTipText);
        }
 

        ///  
        /// Called when the mouse cursor is in designer bounds. 
        /// 
        /// MouseEventArgs containing event data. 
        protected virtual void OnMouseHover(MouseEventArgs e)
        {
            if (e == null)
                throw new ArgumentNullException("e"); 

            if (IsVisible) 
                ShowInfoTip(InfoTipTitle, InfoTipText); 
        }
 
        /// 
        /// Called when the moused button is released when mouse cursor is in designer bounds.
        /// 
        /// MouseEventArgs containing event data. 
        protected virtual void OnMouseUp(MouseEventArgs e)
        { 
            if (e == null) 
                throw new ArgumentNullException("e");
        } 

        /// 
        /// Called when the mouse button is clicked multiple times on the designer
        ///  
        /// MouseEventArgs containing event data.
        protected virtual void OnMouseDoubleClick(MouseEventArgs e) 
        { 
            if (e == null)
                throw new ArgumentNullException("e"); 
        }

        /// 
        /// Called when the mouse cursor leaves designer bounds. 
        /// 
        protected virtual void OnMouseLeave() 
        { 
            if (ShowSmartTag)
                SmartTagVisible = false; 

            ShowInfoTip(String.Empty);
        }
 
        /// 
        /// Called when the mouse capture changes 
        ///  
        protected virtual void OnMouseCaptureChanged()
        { 
        }

        /// 
        /// Called when the drag drop operation is in progress and mouse cursor enters the designer bounds. 
        /// 
        /// Drag drop event arguments. 
        protected virtual void OnDragEnter(ActivityDragEventArgs e) 
        {
            if (e == null) 
                throw new ArgumentNullException("e");
        }

        ///  
        /// Called when the drag drop operation is in progress and mouse cursor is inside the designer bounds.
        ///  
        /// Drag drop event arguments. 
        protected virtual void OnDragOver(ActivityDragEventArgs e)
        { 
            if (e == null)
                throw new ArgumentNullException("e");
        }
 
        /// 
        /// Called when the drag drop operation is in progress and mouse cursor leaves the designer bounds. 
        ///  
        protected virtual void OnDragLeave()
        { 
        }

        /// 
        /// Called when the drag drop operation is completed inside designer bounds. 
        /// 
        /// Drag drop event arguments. 
        protected virtual void OnDragDrop(ActivityDragEventArgs e) 
        {
            if (e == null) 
                throw new ArgumentNullException("e");
        }

        ///  
        /// Updates the visual cues for feedback given to the user when performing drag drop operation.
        ///  
        /// A GiveFeedbackEventArgs that contains the event data. 
        protected virtual void OnGiveFeedback(GiveFeedbackEventArgs e)
        { 
            if (e == null)
                throw new ArgumentNullException("e");
        }
 
        /// 
        /// Controls if the drag drop operation should continue. 
        ///  
        /// A QueryContinueDragEventArgs that contains the event data.
        protected virtual void OnQueryContinueDrag(QueryContinueDragEventArgs e) 
        {
            if (e == null)
                throw new ArgumentNullException("e");
        } 

        ///  
        /// Called when key is pressed when designer has keyboard focus. 
        /// 
        ///  
        protected virtual void OnKeyDown(KeyEventArgs e)
        {
            if (e == null)
                throw new ArgumentNullException("e"); 
        }
 
        ///  
        /// Called when key is released when designer has keyboard focus.
        ///  
        /// 
        protected virtual void OnKeyUp(KeyEventArgs e)
        {
            if (e == null) 
                throw new ArgumentNullException("e");
        } 
 
        /// 
        /// Called when scroll position is changed 
        /// 
        /// Scrollbar sending the message
        /// New value of the scrolled position
        protected virtual void OnScroll(ScrollBar sender, int value) 
        {
        } 
 
        /// 
        /// Allows designer to process raw win32 message 
        /// 
        /// Message structure containing details of the message to be processed
        protected virtual void OnProcessMessage(Message message)
        { 
        }
 
        ///  
        /// Called to refresh the configuration errors associated with designers.
        ///  
        protected internal virtual void RefreshDesignerActions()
        {
            this.designerActions = null;
        } 

        ///  
        /// Called when user clicks on configuration errors associated with the designer. 
        /// 
        /// Designer action associated with configuration error. 
        protected internal virtual void OnExecuteDesignerAction(DesignerAction designerAction)
        {
            if (designerAction == null)
                throw new ArgumentNullException("designerAction"); 

            ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService; 
            if (selectionService != null) 
                selectionService.SetSelectedComponents(new object[] { Activity }, SelectionTypes.Replace);
 
            string propName = designerAction.PropertyName as string;
            if (propName != null && propName.Length > 0)
            {
                IExtendedUIService uiService = GetService(typeof(IExtendedUIService)) as IExtendedUIService; 
                if (uiService != null)
                    uiService.NavigateToProperty(propName); 
            } 
        }
 
        /// 
        /// Called to notify the designer if the SmartTag is being shown or hidden
        /// 
        /// Indicates if the SmartTag is being shown or hidden 
        protected virtual void OnSmartTagVisibilityChanged(bool visible)
        { 
            Rectangle rectangle = smartTag.GetBounds(this, true); 
            Rectangle textRectangle = TextRectangle;
            if (!textRectangle.Size.IsEmpty) 
                rectangle = Rectangle.Union(textRectangle, rectangle);
            Invalidate(rectangle);
        }
 
        /// 
        /// Shows the designer verbs associated with smarttag at specific point 
        ///  
        /// Point at which to show the actions
        protected virtual void OnShowSmartTagVerbs(Point smartTagPoint) 
        {
            ActivityDesignerVerb[] verbs = null;
            SmartTagVerbs.CopyTo(verbs, 0);
            DesignerHelpers.ShowDesignerVerbs(this, PointToScreen(smartTagPoint), verbs); 
        }
 
        ///  
        /// Notifies the designer that the associated theme has changed.
        ///  
        protected virtual void OnThemeChange(ActivityDesignerTheme newTheme)
        {
            if (newTheme == null)
                throw new ArgumentNullException("newTheme"); 

            this.Image = StockImage; 
        } 

        ///  
        /// Stores the UI state of the designer in binary stream.
        /// 
        /// BinaryWriter used to store the state.
        protected virtual void SaveViewState(BinaryWriter writer) 
        {
            if (writer == null) 
                throw new ArgumentNullException("writer"); 
        }
 
        /// 
        /// Restores the UI state of the designer from binary stream.
        /// 
        /// BinaryReader used to restore the designer state. 
        /// 
        protected virtual void LoadViewState(BinaryReader reader) 
        { 
            if (reader == null)
                throw new ArgumentNullException("reader"); 
        }

        /// 
        /// Return if an activity type is valid in context of a root designer. This function is called only if 
        /// the designer is a root designer
        ///  
        /// Type of the activity being queried 
        /// 
        protected virtual bool IsSupportedActivityType(Type activityType) 
        {
            return true;
        }
 
        protected virtual WorkflowView CreateView(ViewTechnology viewTechnology)
        { 
            WorkflowView workflowView = new WorkflowView(Activity.Site as IServiceProvider); 
            workflowView.ShowToolContainer = true;
            return workflowView; 
        }

        /// 
        /// Refreshes the ActivityDesignerVerbs associted with the designer by calling status handler. 
        /// 
        protected void RefreshDesignerVerbs() 
        { 
            if (Activity != null && Activity.Site != null)
            { 
                DesignerVerbCollection verbs = ((IDesigner)this).Verbs;
                if (verbs != null)
                {
                    foreach (DesignerVerb verb in verbs) 
                    {
                        //This will cause us to send the status update for ActivityDesignerVerb 
                        int status = verb.OleStatus; 
                        status = 0;
                    } 
                }
            }
        }
 
        /// 
        /// Draws the visual representation of activity at design time. 
        ///  
        /// ActivityDesignerPaintEventArgs holding drawing arguments
        protected virtual void OnPaint(ActivityDesignerPaintEventArgs e) 
        {
            if (e == null)
                throw new ArgumentNullException("e");
 
            ActivityDesignerPaint.DrawDesignerBackground(e.Graphics, this);
 
            if (!String.IsNullOrEmpty(Text) && !TextRectangle.Size.IsEmpty) 
            {
                Font font = (SmartTagVisible) ? e.DesignerTheme.BoldFont : e.DesignerTheme.Font; 
                ActivityDesignerPaint.DrawText(e.Graphics, font, Text, TextRectangle, StringAlignment.Near, e.AmbientTheme.TextQuality, e.DesignerTheme.ForegroundBrush);
            }

            if (Image != null && !ImageRectangle.Size.IsEmpty) 
                ActivityDesignerPaint.DrawImage(e.Graphics, Image, ImageRectangle, DesignerContentAlignment.Fill);
        } 
 
        /// 
        /// Called to layout the position of contained visual cues or designers. 
        /// 
        /// ActivityDesignerLayoutEventArgs holding layout arguments
        protected virtual void OnLayoutPosition(ActivityDesignerLayoutEventArgs e)
        { 
            if (e == null)
                throw new ArgumentNullException("e"); 
        } 

        ///  
        /// Called to set the size of the visual cues or designers contained within the designer.
        /// 
        /// ActivityDesignerLayoutEventArgs holding layout arguments
        protected virtual Size OnLayoutSize(ActivityDesignerLayoutEventArgs e) 
        {
            if (e == null) 
                throw new ArgumentNullException("e"); 

            //GetVisible is an expensive call so we make sure that we keep it buffered in OnLayoutSize 
            //otherwise drawing slows down. The visiblity change always triggers layouting and hence we
            //can safely buffer this variable
            this.isVisible = GetVisible();
 
            if (!String.IsNullOrEmpty(Text))
            { 
                //Calculate the size of the text, we allow 10 characters per line and maximum of 2 lines 
                Size actualTextSize = ActivityDesignerPaint.MeasureString(e.Graphics, e.DesignerTheme.BoldFont, Text, StringAlignment.Center, Size.Empty);
                Size requestedLineSize = actualTextSize; 
                requestedLineSize.Width /= Text.Length;
                requestedLineSize.Width += ((requestedLineSize.Width % Text.Length) > 0) ? 1 : 0;
                requestedLineSize.Width *= Math.Min(Text.Length, ActivityDesigner.MaximumCharsPerLine - 1);
 
                this.textSize.Width = MinimumSize.Width - 2 * e.AmbientTheme.Margin.Width;
                if (Image != null) 
                    this.textSize.Width -= e.DesignerTheme.ImageSize.Width + e.AmbientTheme.Margin.Width; 
                this.textSize.Width = Math.Min(this.textSize.Width, actualTextSize.Width);
                this.textSize.Width = Math.Max(this.textSize.Width, requestedLineSize.Width); 

                //We calculate the text size in onlayoutsize as we get access to the graphics and font information in this function
                this.textSize.Height = requestedLineSize.Height;
                int textLines = actualTextSize.Width / this.textSize.Width; 
                textLines += ((actualTextSize.Width % this.textSize.Width) > 0) ? 1 : 0;
                textLines = Math.Min(textLines, ActivityDesigner.MaximumTextLines); 
                this.textSize.Height *= textLines; 
            }
            else 
            {
                this.textSize = Size.Empty;
            }
 
            Size size = Size.Empty;
            size.Width = 2 * e.AmbientTheme.Margin.Width + ((Image != null) ? (e.DesignerTheme.ImageSize.Width + e.AmbientTheme.Margin.Width) : 0) + this.textSize.Width; 
            size.Height = e.AmbientTheme.Margin.Height + Math.Max(e.DesignerTheme.ImageSize.Height, this.textSize.Height) + e.AmbientTheme.Margin.Height; 
            return size;
        } 

        /// 
        /// Called when the user starts to visually resize the designer when designer is inside freeform designer
        ///  
        /// 
        protected virtual void OnBeginResizing(ActivityDesignerResizeEventArgs e) 
        { 
        }
 
        /// 
        /// Called when the user is visually resizing the designer when designer is inside freeform designer
        /// 
        /// ActivityDesignerResizeEventArgs specifying the edge being used to resize and new bounds 
        protected virtual void OnResizing(ActivityDesignerResizeEventArgs e)
        { 
            FreeformActivityDesigner.SetDesignerBounds(this, e.Bounds); 
        }
 
        /// 
        /// Called when user is done resizing the designer
        /// 
        protected virtual void OnEndResizing() 
        {
            PerformLayout(); 
        } 

        ///  
        /// Called to check if connection can be established between source and target designer
        /// 
        /// Source connection point
        /// Target connection point 
        /// True if connection can be established, false otherwise
        protected virtual bool CanConnect(ConnectionPoint source, ConnectionPoint target) 
        { 
            return true;
        } 

        /// 
        /// Called when connection is established between two connection points
        ///  
        /// Source connection point
        /// Target connection point 
        protected virtual void OnConnected(ConnectionPoint source, ConnectionPoint target) 
        {
        } 

        /// 
        /// Called when the activity associated with the designer is changed.
        ///  
        /// A ActivityChangedEventArgs containing information about what changed.
        protected virtual void OnActivityChanged(ActivityChangedEventArgs e) 
        { 
            if (e == null)
                throw new ArgumentNullException("e"); 

            if (e.Member != null && e.Member.Name != null && e.Member.Name.Equals("Name"))
                this.Text = Activity.Name;
 
            //Whenever property on the component changes we update the verb status
            //We have to do a type descriptor refresh here as we need to not only update the designer verbs 
            //but also the global commands 
            //For contained activity changed we refresh thru the activity list changed
            if (!(e.OldValue is ActivityCollectionChangeEventArgs)) 
                RefreshDesignerVerbs();

            IUIService uiservice = GetService(typeof(IUIService)) as IUIService;
            if (uiservice != null) 
                uiservice.SetUIDirty();
 
            //Clear and refresh the rules text 
            this.rulesText = null;
        } 

        /// 
        /// Shows specified tooltip
        ///  
        /// String specifying the tooltip title
        /// String specifying the tooltip to display 
        protected void ShowInfoTip(string title, string infoTip) 
        {
            WorkflowView parentView = ParentView; 
            if (parentView != null)
                parentView.ShowInfoTip(title, infoTip);
        }
 
        /// 
        /// Shows specified tooltip 
        ///  
        /// String specifying the tooltip to display
        protected void ShowInfoTip(string infoTip) 
        {
            WorkflowView parentView = ParentView;
            if (parentView != null)
                parentView.ShowInfoTip(infoTip); 
        }
 
        ///  
        /// Shows tooltip at specified location
        ///  
        /// String specifying the tooltip to display
        /// Rectangle where to display tooltip
        protected void ShowInPlaceTip(string infoTip, Rectangle rectangle)
        { 
            WorkflowView parentView = ParentView;
            if (parentView != null) 
                parentView.ShowInPlaceToolTip(infoTip, parentView.LogicalRectangleToClient(rectangle)); 
        }
 
        /// 
        /// Updates the layout of the designer
        /// 
        protected void PerformLayout() 
        {
            WorkflowView parentView = ParentView; 
            if (parentView != null) 
                parentView.PerformLayout(false);
        } 

        /// 
        /// Transforms point from activity designer coordinate system to screen
        ///  
        /// Point in activity designer coordinate system
        /// Point in screen coordinate system 
        protected Point PointToScreen(Point point) 
        {
            WorkflowView parentView = ParentView; 
            if (parentView != null)
                return parentView.LogicalPointToScreen(point);
            else
                return point; 
        }
 
        ///  
        /// Transforms point from screen coordinate system to activity designer coordinate system
        ///  
        /// Point in screen coordinate system
        /// Point in activity designer coordinate system
        protected Point PointToLogical(Point point)
        { 
            WorkflowView parentView = ParentView;
            if (parentView != null) 
                return parentView.ScreenPointToLogical(point); 
            else
                return point; 
        }

        /// 
        /// Transforms rectangle from activity designer coordinate system to screen 
        /// 
        /// Rectangle in activity designer coordinate system 
        /// Rectangle in screen coordinate system 
        protected Rectangle RectangleToScreen(Rectangle rectangle)
        { 
            WorkflowView parentView = ParentView;
            if (parentView != null)
                return new Rectangle(PointToScreen(rectangle.Location), parentView.LogicalSizeToClient(rectangle.Size));
            else 
                return rectangle;
 
        } 

        //for the accessible object 
        internal Rectangle InternalRectangleToScreen(Rectangle rectangle)
        {
            return RectangleToScreen(rectangle);
        } 

        ///  
        /// Transforms rectangle from screen coordinate system to activity designer coordinate system 
        /// 
        /// Rectangle in screen coordinate system 
        /// Rectangle in activity designer coordinate system
        protected Rectangle RectangleToLogical(Rectangle rectangle)
        {
            WorkflowView parentView = ParentView; 
            if (parentView != null)
                return new Rectangle(PointToLogical(rectangle.Location), parentView.ClientSizeToLogical(rectangle.Size)); 
            else 
                return rectangle;
        } 
        #endregion

        #region Private static Methods
        internal static ActivityDesigner GetSafeRootDesigner(IServiceProvider serviceProvider) 
        {
            return (serviceProvider != null) ? ActivityDesigner.GetRootDesigner(serviceProvider) : null; 
        } 

        internal static ActivityDesigner GetDesigner(Activity activity) 
        {
            ActivityDesigner designer = null;

            if (activity != null && activity.Site != null) 
            {
                IDesignerHost designerHost = activity.Site.GetService(typeof(IDesignerHost)) as IDesignerHost; 
                if (designerHost != null) 
                    designer = designerHost.GetDesigner(activity) as ActivityDesigner;
            } 

            return designer;
        }
 
        internal static string GetActivityDescription(Type activityType)
        { 
            if (activityType == null) 
                return null;
 
            object[] attribs = activityType.GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (attribs != null && attribs.GetLength(0) == 0)
                attribs = activityType.GetCustomAttributes(typeof(DescriptionAttribute), true);
 
            DescriptionAttribute descriptionAttribute = (attribs != null && attribs.GetLength(0) > 0) ? attribs[0] as DescriptionAttribute : null;
            return (descriptionAttribute != null) ? descriptionAttribute.Description : String.Empty; 
        } 

        internal static CompositeActivityDesigner GetParentDesigner(object obj) 
        {
            // get parent designer
            CompositeActivityDesigner parentDesigner = null;
            if (obj is HitTestInfo) 
            {
                parentDesigner = ((HitTestInfo)obj).AssociatedDesigner as CompositeActivityDesigner; 
            } 
            else if (obj is Activity)
            { 
                ActivityDesigner activityDesigner = ActivityDesigner.GetDesigner(obj as Activity);
                if (activityDesigner != null)
                    parentDesigner = activityDesigner.ParentDesigner;
            } 

            return parentDesigner; 
        } 

        internal static ActivityDesigner CreateTransientDesigner(Activity activity) 
        {
            ActivityDesigner activityDesigner = new ActivityDesigner();
            ActivityDesignerTheme designerTheme = activityDesigner.DesignerTheme;
 
            using (Bitmap temporaryBitmap = new Bitmap(designerTheme.Size.Width, designerTheme.Size.Height, PixelFormat.Format32bppArgb))
            using (Graphics graphics = Graphics.FromImage(temporaryBitmap)) 
            { 
                activityDesigner.Image = ActivityToolboxItem.GetToolboxImage(activity.GetType());
                activityDesigner.Location = new Point(-1, -1); 
                activityDesigner.Location = Point.Empty;
                activityDesigner.Size = activityDesigner.OnLayoutSize(new ActivityDesignerLayoutEventArgs(graphics, activityDesigner.DesignerTheme));
            }
 
            return activityDesigner;
        } 
 
        internal static Type GetDesignerType(IServiceProvider serviceProvider, Type activityType, Type designerBaseType)
        { 
            Type designerType = null;
            AttributeCollection attribs = TypeDescriptor.GetAttributes(activityType);
            foreach (Attribute attribute in attribs)
            { 
                DesignerAttribute designerAttribute = attribute as DesignerAttribute;
                if (designerAttribute != null && (designerBaseType == null || designerAttribute.DesignerBaseTypeName == designerBaseType.AssemblyQualifiedName)) 
                { 
                    int index = designerAttribute.DesignerTypeName.IndexOf(',');
                    string designerTypeName = (index >= 0) ? designerAttribute.DesignerTypeName.Substring(0, index) : designerAttribute.DesignerTypeName; 
                    designerType = activityType.Assembly.GetType(designerTypeName);
                    if (designerType == null && serviceProvider != null)
                    {
                        ITypeResolutionService typeResolutionService = serviceProvider.GetService(typeof(ITypeResolutionService)) as ITypeResolutionService; 
                        designerType = (typeResolutionService != null) ? typeResolutionService.GetType(designerAttribute.DesignerTypeName) : null;
                    } 
 
                    if (designerType == null)
                        designerType = Type.GetType(designerAttribute.DesignerTypeName); 

                    break;
                }
            } 

            return designerType; 
        } 

        internal static ActivityDesigner CreateDesigner(IServiceProvider serviceProvider, Activity activity) 
        {
            IDesigner designer = null;
            Type designerType = GetDesignerType(serviceProvider, activity.GetType(), typeof(IDesigner));
            if (designerType == null) 
                designerType = GetDesignerType(serviceProvider, activity.GetType(), null);
 
            if (designerType != null) 
            {
                try 
                {
                    designer = Activator.CreateInstance(designerType, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, null, null) as IDesigner;
                    designer.Initialize(activity);
                } 
                catch
                { 
                    //Eat the exception thrown 
                }
            } 
            return (designer as ActivityDesigner);
        }
        #endregion
 
        #region Private Methods
        private bool GetVisible() 
        { 
            Activity activity = Activity;
            if (activity == null) 
                return false;

            while (activity != null)
            { 
                ActivityDesigner containedDesigner = ActivityDesigner.GetDesigner(activity);
                if (containedDesigner != null) 
                { 
                    CompositeActivityDesigner parentDesigner = containedDesigner.ParentDesigner;
                    if (parentDesigner == null && containedDesigner is IRootDesigner) 
                        return true;

                    if (parentDesigner == null || !parentDesigner.Expanded || !parentDesigner.IsContainedDesignerVisible(containedDesigner))
                        return false; 

                    activity = parentDesigner.Activity; 
                } 
                else
                { 
                    activity = null;
                }
            }
            return true; 
        }
 
        private void OnGenerateEventHandler(object sender, EventArgs e) 
        {
            DesignerVerb eventVerb = sender as DesignerVerb; 
            if (eventVerb == null)
                return;

            Activity contextActivity = Helpers.GetRootActivity(Activity); 
            if (contextActivity == null)
                return; 
 
            PropertyDescriptor methodDescriptor = null;
 
            PropertyDescriptor[] propertyDescriptors = EventHandlerProperties;
            foreach (PropertyDescriptor propertyDescriptor in propertyDescriptors)
            {
                Type rtType = PropertyDescriptorUtils.GetBaseType(propertyDescriptor, Activity, Activity.Site); 
                if (rtType != null)
                { 
                    object handler = propertyDescriptor.GetValue(Activity); 
                    if (!(handler is String) || String.IsNullOrEmpty((String)handler))
                        handler = DesignerHelpers.CreateUniqueMethodName(Activity, propertyDescriptor.Name, rtType); 
                    propertyDescriptor.SetValue(Activity, handler);
                    methodDescriptor = propertyDescriptor;
                }
            } 

            IEventBindingService eventBindingService = GetService(typeof(IEventBindingService)) as IEventBindingService; 
            if (eventBindingService != null) 
            {
                if (methodDescriptor is DynamicPropertyDescriptor) 
                    methodDescriptor = ((DynamicPropertyDescriptor)methodDescriptor).RealPropertyDescriptor;

                EventDescriptor eventDescriptor = eventBindingService.GetEvent(methodDescriptor);
                if (eventDescriptor != null) 
                    eventBindingService.ShowCode(Activity, eventDescriptor);
                else 
                    eventBindingService.ShowCode(); 
            }
        } 

        private void OnPromoteBindings(object sender, EventArgs e)
        {
            DesignerVerb eventVerb = sender as DesignerVerb; 
            if (eventVerb == null)
                return; 
 
            IServiceProvider serviceProvider = GetService(typeof(DesignSurface)) as IServiceProvider;
            Debug.Assert(serviceProvider != null); 

            List properties = CustomActivityDesignerHelper.GetCustomProperties(serviceProvider);
            if (properties == null)
                return; 

            // get all the members of the custom activity to ensure uniqueness 
            Type customActivityType = CustomActivityDesignerHelper.GetCustomActivityType(serviceProvider); 
            List customPropertyNames = new List();
            foreach (MemberInfo memberInfo in customActivityType.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) 
            {
                if (!customPropertyNames.Contains(memberInfo.Name))
                    customPropertyNames.Add(memberInfo.Name);
            } 

            PropertyDescriptor[] propertyDescriptors = BindableProperties; 
            Dictionary promotedProperties = new Dictionary(); 

            foreach (PropertyDescriptor propertyDescriptor in propertyDescriptors) 
            {
                ActivityBind bind = propertyDescriptor.GetValue(Activity) as ActivityBind;
                if (bind != null)
                    continue; 

                CustomProperty newCustomProperty = CustomProperty.CreateCustomProperty(Activity.Site, DesignerHelpers.GenerateUniqueIdentifier(Activity.Site, Activity.Name + "_" + propertyDescriptor.Name, customPropertyNames.ToArray()), propertyDescriptor, Activity); 
 
                properties.Add(newCustomProperty);
 
                // verify this name will not repeat
                customPropertyNames.Add(newCustomProperty.Name);

                // set a new bind 
                promotedProperties.Add(propertyDescriptor, new ActivityBind(ActivityBind.GetRelativePathExpression(Helpers.GetRootActivity(Activity), Activity), newCustomProperty.Name));
            } 
 
            //We have a restriction that we need to emit the custom properties furst before setting the binding
            CustomActivityDesignerHelper.SetCustomProperties(properties, serviceProvider); 

            foreach (PropertyDescriptor promotedProperty in promotedProperties.Keys)
                promotedProperty.SetValue(Activity, promotedProperties[promotedProperty]);
        } 

        private void OnBindProperty(object sender, EventArgs e) 
        { 
            IExtendedUIService extendedUIService = GetService(typeof(IExtendedUIService)) as IExtendedUIService;
            if (extendedUIService != null) 
                BindUITypeEditor.EditValue(extendedUIService.GetSelectedPropertyContext());
        }

        private void OnGenerateEventHandlerStatusUpdate(object sender, EventArgs e) 
        {
            DesignerVerb verb = sender as DesignerVerb; 
            if (verb == null) 
                return;
 
            bool canGenerateHandlers = false;
            PropertyDescriptor[] propertyDescriptors = EventHandlerProperties;
            foreach (PropertyDescriptor propertyDescriptor in propertyDescriptors)
            { 
                object handler = propertyDescriptor.GetValue(Activity);
                if (handler == null) 
                { 
                    canGenerateHandlers = true;
                    break; 
                }
            }

            verb.Enabled = canGenerateHandlers; 
        }
 
        private void OnPromoteBindingsStatusUpdate(object sender, EventArgs e) 
        {
            DesignerVerb verb = sender as DesignerVerb; 
            if (verb == null)
                return;

            bool canPromoteBindings = false; 
            PropertyDescriptor[] propertyDescriptors = this.BindableProperties;
            foreach (PropertyDescriptor propertyDescriptor in propertyDescriptors) 
            { 
                ActivityBind bind = propertyDescriptor.GetValue(Activity) as ActivityBind;
                if (bind == null) 
                {
                    canPromoteBindings = true;
                    break;
                } 
            }
            verb.Enabled = canPromoteBindings; 
        } 

        private void OnBindPropertyStatusUpdate(object sender, EventArgs e) 
        {
            DesignerVerb verb = sender as DesignerVerb;
            if (verb == null)
                return; 

            bool canBindProperty = false; 
            string propertyName = null; 
            IExtendedUIService extendedUIService = GetService(typeof(IExtendedUIService)) as IExtendedUIService;
            if (extendedUIService != null) 
            {
                ITypeDescriptorContext propertyContext = extendedUIService.GetSelectedPropertyContext();
                canBindProperty = (propertyContext != null && ActivityBindPropertyDescriptor.IsBindableProperty(propertyContext.PropertyDescriptor) && !propertyContext.PropertyDescriptor.IsReadOnly);
                propertyName = (propertyContext != null) ? propertyContext.PropertyDescriptor.Name : null; 
            }
 
            verb.Properties["Text"] = (propertyName != null && verb.Enabled) ? string.Format(CultureInfo.CurrentCulture, DR.GetString(DR.BindSelectedPropertyFormat), propertyName) : DR.GetString(DR.BindSelectedProperty); 
            verb.Enabled = (canBindProperty && !IsLocked);
        } 

        private void OnComponentRenamed(object sender, ComponentRenameEventArgs e)
        {
            ActivityDesigner designer = ActivityDesigner.GetDesigner(e.Component as Activity); 
            if (designer != null)
                this.Text = Activity.Name; 
 
        }
 
        private void OnComponentChanged(object sender, ComponentChangedEventArgs e)
        {
            if (e.Component != null && (e.OldValue is ActivityBind && !(e.NewValue is ActivityBind)) ||
                (!(e.OldValue is ActivityBind) && e.NewValue is ActivityBind)) 
                TypeDescriptor.Refresh(e.Component);
 
            IReferenceService referenceService = GetService(typeof(IReferenceService)) as IReferenceService; 
            Activity changedActivity = (referenceService != null) ? referenceService.GetComponent(e.Component) as Activity : e.Component as Activity;
            if (changedActivity != null) 
            {
                ActivityDesigner designer = ActivityDesigner.GetDesigner(changedActivity);
                if (designer != null)
                    designer.OnActivityChanged(new ActivityChangedEventArgs(changedActivity, e.Member, e.OldValue, e.NewValue)); 
            }
        } 
 
        private void OnLoadComplete(object sender, EventArgs e)
        { 
            WorkflowView workflowView = ((IRootDesigner)this).GetView(ViewTechnology.Default) as WorkflowView;
            if (workflowView != null)
                workflowView.Idle += new EventHandler(OnFirstIdle);
        } 

        private void OnFirstIdle(object sender, EventArgs e) 
        { 
            WorkflowView workflowView = ((IRootDesigner)this).GetView(ViewTechnology.Default) as WorkflowView;
            if (workflowView != null) 
                workflowView.Idle -= new EventHandler(OnFirstIdle);

            // Select this component.
            ISelectionService selectionService = (ISelectionService)GetService(typeof(ISelectionService)); 
            if (selectionService != null && selectionService.SelectionCount == 0)
                selectionService.SetSelectedComponents(new object[] { Activity }, SelectionTypes.Replace); 
 
            DesignerHelpers.RefreshDesignerActions(Activity.Site);
            Invalidate(); 
        }
        #endregion

        #endregion 

        #region Interface Implementation 
 
        #region IDisposable Implementation
        public void Dispose() 
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        } 
        #endregion
 
        #region IDesigner Implementation 
        IComponent IDesigner.Component
        { 
            get
            {
                return this.activity as IComponent;
            } 
        }
 
        DesignerVerbCollection IDesigner.Verbs 
        {
            get 
            {
                ActivityDesignerVerbCollection verbs = new ActivityDesignerVerbCollection();
                verbs.AddRange(Verbs);
 
                IDesignerVerbProviderService verbProviderService = GetService(typeof(IDesignerVerbProviderService)) as IDesignerVerbProviderService;
                if (verbProviderService != null) 
                { 
                    foreach (IDesignerVerbProvider verbProvider in verbProviderService.VerbProviders)
                        verbs.AddRange(verbProvider.GetVerbs(this)); 
                }

                return verbs.SafeCollection;
            } 
        }
 
        void IDesigner.Initialize(IComponent component) 
        {
            this.activity = component as Activity; 
            if (this.activity == null)
                throw new ArgumentException(DR.GetString(DR.Error_InvalidActivity), "component");

            Initialize(this.activity); 
        }
 
        void IDesigner.DoDefaultAction() 
        {
            DoDefaultAction(); 
        }
        #endregion

        #region IDesignerFilter Implementation 
        void IDesignerFilter.PreFilterAttributes(IDictionary attributes)
        { 
            PreFilterAttributes(attributes); 
        }
 
        void IDesignerFilter.PreFilterProperties(IDictionary properties)
        {
            PreFilterProperties(properties);
        } 

        void IDesignerFilter.PreFilterEvents(IDictionary events) 
        { 
            PreFilterEvents(events);
        } 

        void IDesignerFilter.PostFilterAttributes(IDictionary attributes)
        {
            PostFilterAttributes(attributes); 
        }
 
        void IDesignerFilter.PostFilterProperties(IDictionary properties) 
        {
            PostFilterProperties(properties); 
        }

        void IDesignerFilter.PostFilterEvents(IDictionary events)
        { 
            PostFilterEvents(events);
        } 
        #endregion 

        #region IConnectableDesigner Implementation 
        bool IConnectableDesigner.CanConnect(ConnectionPoint source, ConnectionPoint target)
        {
            return CanConnect(source, target);
        } 

        void IConnectableDesigner.OnConnected(ConnectionPoint source, ConnectionPoint target) 
        { 
            OnConnected(source, target);
        } 
        #endregion

        #region IWorkflowRootDesigner Implementation
        ViewTechnology[] IRootDesigner.SupportedTechnologies 
        {
            get 
            { 
                return new ViewTechnology[] { ViewTechnology.Default };
            } 
        }

        object IRootDesigner.GetView(ViewTechnology technology)
        { 
            DesignSurface surface = GetService(typeof(DesignSurface)) as DesignSurface;
            IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost; 
            if (this.workflowView == null && surface != null && designerHost != null && designerHost.RootComponent == Activity) 
                this.workflowView = CreateView(technology);
            return this.workflowView; 
        }

        CompositeActivityDesigner IWorkflowRootDesigner.InvokingDesigner
        { 
            get
            { 
                return InvokingDesigner; 
            }
 
            set
            {
                InvokingDesigner = value;
            } 
        }
 
        ReadOnlyCollection IWorkflowRootDesigner.MessageFilters 
        {
            get 
            {
                return MessageFilters;
            }
        } 

        bool IWorkflowRootDesigner.IsSupportedActivityType(Type activityType) 
        { 
            return IsSupportedActivityType(activityType);
        } 

        bool IWorkflowRootDesigner.SupportsLayoutPersistence
        {
            get 
            {
                return SupportsLayoutPersistence; 
            } 
        }
        #endregion 

        #region IToolboxUser Implementation
        bool IToolboxUser.GetToolSupported(ToolboxItem toolboxItem)
        { 
            // Default is true.  If any goes wrong, let the compiler catch it.
            bool itemSupported = true; 
 
            //get ui service refernce
            IExtendedUIService2 uiService = this.GetService(typeof(IExtendedUIService2)) as IExtendedUIService2; 
            //and use it to obtain project's target framework version
            if (null != uiService)
            {
                //in case of target framework less than 3.5 - disable ReceiveActivity and SendActivity 
                long targetFramework = uiService.GetTargetFrameworkVersion();
 
                if (targetFramework != 0) 
                {
                    // if target framework is less than 3.0 dont show any toolbox item, because workflow didnt ship then. 
                    if (targetFramework < ActivityDesigner.FrameworkVersion_3_0)
                    {
                        return false;
                    } 

                    if (targetFramework < ActivityDesigner.FrameworkVersion_3_5) 
                    { 
                        if (string.Equals(toolboxItem.TypeName, "System.Workflow.Activities.ReceiveActivity") ||
                            string.Equals(toolboxItem.TypeName, "System.Workflow.Activities.SendActivity")) 
                        {
                            return false;
                        }
                    } 
                }
            } 
 
            ITypeProvider typeProvider = GetService(typeof(ITypeProvider)) as ITypeProvider;
            if (typeProvider != null) 
            {
                Type itemType = null;
                if (typeProvider.LocalAssembly != null)
                    itemType = typeProvider.LocalAssembly.GetType(toolboxItem.TypeName, false); 
                if (itemType == null)
                { 
                    try 
                    {
                        itemType = Type.GetType(toolboxItem.TypeName + ", " + toolboxItem.AssemblyName); 
                    }
                    catch (FileNotFoundException) { }
                    catch (FileLoadException) { }
                } 

                if (itemType == null) 
                    return itemSupported; 

                //check if the activity is NOT supported - we ask this to the Root Designer only. If so, bail out. 
                IWorkflowRootDesigner rootDesigner = ActivityDesigner.GetSafeRootDesigner(Activity.Site) as IWorkflowRootDesigner;
                if (rootDesigner != null)
                {
                    if (!rootDesigner.IsSupportedActivityType(itemType)) 
                    {
                        return false; 
                    } 
                    else if (rootDesigner.InvokingDesigner != null && rootDesigner.InvokingDesigner.Activity != null)
                    { 
                        rootDesigner = ActivityDesigner.GetSafeRootDesigner(rootDesigner.InvokingDesigner.Activity.Site) as IWorkflowRootDesigner;
                        if (rootDesigner != null && !rootDesigner.IsSupportedActivityType(itemType))
                            return false;
                    } 
                }
 
                if (!(toolboxItem is ActivityToolboxItem)) 
                {
                    object[] attributes = itemType.GetCustomAttributes(typeof(ToolboxItemAttribute), false); 
                    if (attributes.Length > 0)
                    {
                        itemSupported = false;
                        foreach (Attribute attribute in attributes) 
                        {
                            ToolboxItemAttribute toolBoxItemAttribute = attribute as ToolboxItemAttribute; 
                            if (toolBoxItemAttribute != null && typeof(System.Workflow.ComponentModel.Design.ActivityToolboxItem).IsAssignableFrom(toolBoxItemAttribute.ToolboxItemType)) 
                            {
                                itemSupported = true; 
                                break;
                            }
                        }
                    } 
                }
            } 
            return itemSupported; 
        }
 
        void IToolboxUser.ToolPicked(ToolboxItem toolboxItem)
        {
            ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
            IToolboxService toolboxService = GetService(typeof(IToolboxService)) as IToolboxService; 
            if (toolboxItem == null || selectionService == null)
                return; 
 
            object selectedObject = selectionService.PrimarySelection;
            if (!(selectedObject is HitTestInfo) && !(selectedObject is CompositeActivity)) 
                return;

            //Get the paste target
            HitTestInfo hitInfo = null; 
            CompositeActivity compositeActivity = null;
            if (selectedObject is HitTestInfo) 
            { 
                hitInfo = (HitTestInfo)selectedObject;
                compositeActivity = hitInfo.AssociatedDesigner.Activity as CompositeActivity; 
            }
            else if (selectedObject is CompositeActivity)
            {
                compositeActivity = (CompositeActivity)selectedObject; 
                hitInfo = new HitTestInfo(ActivityDesigner.GetDesigner(compositeActivity), HitTestLocations.Designer);
            } 
 
            //Get the parent designer for pasting
            CompositeActivityDesigner compositeActivityDesigner = ActivityDesigner.GetDesigner(compositeActivity) as CompositeActivityDesigner; 
            if (compositeActivityDesigner == null)
                return;

 
            Activity[] activities = CompositeActivityDesigner.DeserializeActivitiesFromToolboxItem(Activity.Site, toolboxItem, false);
            if (activities.Length == 0) 
                return; 

            if (!compositeActivityDesigner.CanInsertActivities(hitInfo, new List(activities).AsReadOnly())) 
                return;

            try
            { 
                activities = CompositeActivityDesigner.DeserializeActivitiesFromToolboxItem(Activity.Site, toolboxItem, true);
                if (activities.Length > 0) 
                { 
                    CompositeActivityDesigner.InsertActivities(compositeActivityDesigner, hitInfo, new List(activities).AsReadOnly(), SR.GetString(SR.PastingActivities));
                    selectionService.SetSelectedComponents(activities, SelectionTypes.Replace); 
                    ParentView.EnsureVisible(activities[0]);
                }
            }
            catch (CheckoutException ex) 
            {
                if (ex != CheckoutException.Canceled) 
                    throw new Exception(DR.GetString(DR.ActivityInsertError) + "\n" + ex.Message, ex); 
            }
        } 
        #endregion

        #region IPersistUIState Implementation
        void IPersistUIState.SaveViewState(BinaryWriter writer) 
        {
            SaveViewState(writer); 
        } 

        void IPersistUIState.LoadViewState(BinaryReader reader) 
        {
            LoadViewState(reader);
        }
        #endregion 

        #region IWorkflowDesignerMessageSink Members 
        bool IWorkflowDesignerMessageSink.OnMouseDown(MouseEventArgs e) 
        {
            WorkflowView parentView = ParentView; 
            if (parentView != null)
            {
                try
                { 
                    Point logicalPoint = parentView.ClientPointToLogical(new Point(e.X, e.Y));
                    OnMouseDown(new MouseEventArgs(e.Button, e.Clicks, logicalPoint.X, logicalPoint.Y, e.Delta)); 
                } 
                catch
                { 
                }
            }
            return true;
        } 

        bool IWorkflowDesignerMessageSink.OnMouseMove(MouseEventArgs e) 
        { 
            WorkflowView parentView = ParentView;
            if (parentView != null) 
            {
                try
                {
                    Point logicalPoint = parentView.ClientPointToLogical(new Point(e.X, e.Y)); 
                    OnMouseMove(new MouseEventArgs(e.Button, e.Clicks, logicalPoint.X, logicalPoint.Y, e.Delta));
                } 
                catch 
                {
                } 
            }
            return true;
        }
 
        bool IWorkflowDesignerMessageSink.OnMouseUp(MouseEventArgs e)
        { 
            WorkflowView parentView = ParentView; 
            if (parentView != null)
            { 
                try
                {
                    Point logicalPoint = parentView.ClientPointToLogical(new Point(e.X, e.Y));
                    OnMouseUp(new MouseEventArgs(e.Button, e.Clicks, logicalPoint.X, logicalPoint.Y, e.Delta)); 
                }
                catch 
                { 
                }
            } 
            return true;
        }

        bool IWorkflowDesignerMessageSink.OnMouseDoubleClick(MouseEventArgs e) 
        {
            WorkflowView parentView = ParentView; 
            if (parentView != null) 
            {
                try 
                {
                    Point logicalPoint = parentView.ClientPointToLogical(new Point(e.X, e.Y));
                    OnMouseDoubleClick(new MouseEventArgs(e.Button, e.Clicks, logicalPoint.X, logicalPoint.Y, e.Delta));
                } 
                catch
                { 
                } 
            }
            return true; 
        }

        bool IWorkflowDesignerMessageSink.OnMouseEnter(MouseEventArgs e)
        { 
            WorkflowView parentView = ParentView;
            if (parentView != null) 
            { 
                try
                { 
                    Point logicalPoint = parentView.ClientPointToLogical(new Point(e.X, e.Y));
                    OnMouseEnter(new MouseEventArgs(e.Button, e.Clicks, logicalPoint.X, logicalPoint.Y, e.Delta));
                }
                catch 
                {
                } 
            } 
            return true;
        } 

        bool IWorkflowDesignerMessageSink.OnMouseHover(MouseEventArgs e)
        {
            WorkflowView parentView = ParentView; 
            if (parentView != null)
            { 
                try 
                {
                    Point logicalPoint = parentView.ClientPointToLogical(new Point(e.X, e.Y)); 
                    OnMouseHover(new MouseEventArgs(e.Button, e.Clicks, logicalPoint.X, logicalPoint.Y, e.Delta));
                }
                catch
                { 
                }
            } 
            return true; 
        }
 
        bool IWorkflowDesignerMessageSink.OnMouseLeave()
        {
            try
            { 
                OnMouseLeave();
            } 
            catch 
            {
            } 

            return true;
        }
 
        bool IWorkflowDesignerMessageSink.OnMouseWheel(MouseEventArgs e)
        { 
            //Only used in message filters 
            return true;
        } 

        bool IWorkflowDesignerMessageSink.OnMouseCaptureChanged()
        {
            try 
            {
                OnMouseCaptureChanged(); 
            } 
            catch
            { 
            }

            return true;
        } 

        bool IWorkflowDesignerMessageSink.OnMouseDragBegin(Point initialPoint, MouseEventArgs e) 
        { 
            WorkflowView parentView = ParentView;
            if (parentView != null) 
            {
                try
                {
                    Point logicalPoint = parentView.ClientPointToLogical(new Point(e.X, e.Y)); 
                    OnMouseDragBegin(initialPoint, new MouseEventArgs(e.Button, e.Clicks, logicalPoint.X, logicalPoint.Y, e.Delta));
                } 
                catch 
                {
                } 
            }
            return true;
        }
 
        bool IWorkflowDesignerMessageSink.OnMouseDragMove(MouseEventArgs e)
        { 
            WorkflowView parentView = ParentView; 
            if (parentView != null)
            { 
                try
                {
                    Point logicalPoint = parentView.ClientPointToLogical(new Point(e.X, e.Y));
                    OnMouseDragMove(new MouseEventArgs(e.Button, e.Clicks, logicalPoint.X, logicalPoint.Y, e.Delta)); 
                }
                catch 
                { 
                }
            } 
            return true;
        }

        bool IWorkflowDesignerMessageSink.OnMouseDragEnd() 
        {
            try 
            { 
                OnMouseDragEnd();
            } 
            catch
            {
            }
            return true; 
        }
 
        bool IWorkflowDesignerMessageSink.OnDragEnter(DragEventArgs e) 
        {
            try 
            {
                OnDragEnter(e as ActivityDragEventArgs);
            }
            catch 
            {
            } 
            return true; 
        }
 
        bool IWorkflowDesignerMessageSink.OnDragOver(DragEventArgs e)
        {
            try
            { 
                OnDragOver(e as ActivityDragEventArgs);
            } 
            catch 
            {
            } 
            return true;
        }

        bool IWorkflowDesignerMessageSink.OnDragLeave() 
        {
            try 
            { 
                OnDragLeave();
            } 
            catch
            {
            }
            return true; 
        }
 
        bool IWorkflowDesignerMessageSink.OnDragDrop(DragEventArgs e) 
        {
            try 
            {
                OnDragDrop(e as ActivityDragEventArgs);
            }
            catch 
            {
            } 
 
            return true;
        } 

        bool IWorkflowDesignerMessageSink.OnGiveFeedback(GiveFeedbackEventArgs e)
        {
            try 
            {
                OnGiveFeedback(e); 
            } 
            catch
            { 
            }
            return true;
        }
 
        bool IWorkflowDesignerMessageSink.OnQueryContinueDrag(QueryContinueDragEventArgs e)
        { 
            try 
            {
                OnQueryContinueDrag(e); 
            }
            catch
            {
            } 
            return true;
        } 
 
        bool IWorkflowDesignerMessageSink.OnKeyDown(KeyEventArgs e)
        { 
            try
            {
                OnKeyDown(e);
            } 
            catch
            { 
            } 
            return true;
        } 

        bool IWorkflowDesignerMessageSink.OnKeyUp(KeyEventArgs e)
        {
            try 
            {
                OnKeyUp(e); 
            } 
            catch
            { 
            }
            return true;
        }
 
        bool IWorkflowDesignerMessageSink.OnScroll(ScrollBar sender, int value)
        { 
            try 
            {
                OnScroll(sender, value); 
            }
            catch
            {
            } 
            return true;
        } 
 
        bool IWorkflowDesignerMessageSink.OnShowContextMenu(Point screenMenuPoint)
        { 
            //Only used in message filters
            return true;
        }
 
        bool IWorkflowDesignerMessageSink.ProcessMessage(Message message)
        { 
            try 
            {
                OnProcessMessage(message); 
            }
            catch
            {
            } 
            return true;
        } 
 
        void IWorkflowDesignerMessageSink.OnLayout(LayoutEventArgs layoutEventArgs)
        { 
            //Only used in message filters
        }

        void IWorkflowDesignerMessageSink.OnLayoutPosition(Graphics graphics) 
        {
            try 
            { 
                OnLayoutPosition(new ActivityDesignerLayoutEventArgs(graphics, DesignerTheme));
            } 
            catch
            {
            }
        } 

        void IWorkflowDesignerMessageSink.OnLayoutSize(Graphics graphics) 
        { 
            try
            { 
                Size = OnLayoutSize(new ActivityDesignerLayoutEventArgs(graphics, DesignerTheme));
            }
            catch
            { 
            }
        } 
 
        void IWorkflowDesignerMessageSink.OnBeginResizing(DesignerEdges sizingEdge)
        { 
            try
            {
                OnBeginResizing(new ActivityDesignerResizeEventArgs(sizingEdge, Bounds));
            } 
            catch
            { 
            } 
        }
 
        void IWorkflowDesignerMessageSink.OnResizing(DesignerEdges sizingEdge, Rectangle bounds)
        {
            try
            { 
                OnResizing(new ActivityDesignerResizeEventArgs(sizingEdge, bounds));
            } 
            catch 
            {
            } 
        }

        void IWorkflowDesignerMessageSink.OnEndResizing()
        { 
            try
            { 
                OnEndResizing(); 
            }
            catch 
            {
            }
        }
 
        void IWorkflowDesignerMessageSink.OnThemeChange()
        { 
            try 
            {
                OnThemeChange(DesignerTheme); 
            }
            catch
            {
            } 
        }
 
        bool IWorkflowDesignerMessageSink.OnPaint(PaintEventArgs e, Rectangle viewPort) 
        {
            try 
            {
                Rectangle bounds = Bounds;
                if (IsVisible && viewPort.IntersectsWith(bounds))
                { 
                    GlyphManager glyphManager = GetService(typeof(IDesignerGlyphProviderService)) as GlyphManager;
                    bounds.Width += 1; bounds.Height += 1; 
 
                    using (GraphicsPath graphicsPath = ActivityDesignerPaint.GetDesignerPath(this, Point.Empty, new Size(DesignerTheme.BorderWidth, DesignerTheme.BorderWidth), DesignerEdges.All, false))
                    using (Region clipRegion = new Region(graphicsPath)) 
                    {
                        Region oldRegion = e.Graphics.Clip;
                        clipRegion.Intersect(oldRegion);
                        clipRegion.Intersect(viewPort); 

                        bool restoredClipState = false; 
                        try 
                        {
                            ActivityDesignerPaintEventArgs eventArgs = new ActivityDesignerPaintEventArgs(e.Graphics, bounds, viewPort, DesignerTheme); 

                            e.Graphics.Clip = clipRegion;
                            OnPaint(eventArgs);
                            e.Graphics.Clip = oldRegion; 
                            restoredClipState = true;
 
                            if (glyphManager != null) 
                                glyphManager.DrawDesignerGlyphs(eventArgs, this);
 
                            DrawingState &= (~DrawingStates.InvalidDraw);
                        }
                        catch
                        { 
                            //Eat the exception thrown
                            DrawingState |= DrawingStates.InvalidDraw; 
                        } 
                        finally
                        { 
                            if (!restoredClipState)
                                e.Graphics.Clip = oldRegion;

                            if (DrawingState != DrawingStates.Valid) 
                                ActivityDesignerPaint.DrawInvalidDesignerIndicator(e.Graphics, this);
                        } 
                    } 
                }
            } 
            catch
            {
            }
            return true; 
        }
 
        bool IWorkflowDesignerMessageSink.OnPaintWorkflowAdornments(PaintEventArgs e, Rectangle viewPort) 
        {
            //Only used in message filters 
            return true;
        }
        #endregion
 
        #endregion
 
        #region Class SmartTag 
        internal sealed class SmartTag : DesignerGlyph
        { 
            internal const int DefaultHeight = 2;
            private static Image defaultImage = DR.GetImage(DR.SmartTag);
            private ActivityDesigner activeDesigner;
 
            public override Rectangle GetBounds(ActivityDesigner designer, bool activated)
            { 
                Rectangle smartTagRectangle = Rectangle.Empty; 
                Rectangle rectangle = designer.SmartTagRectangle;
                if (!rectangle.IsEmpty) 
                {
                    Size glyphSize = WorkflowTheme.CurrentTheme.AmbientTheme.GlyphSize;
                    Size imageSize = rectangle.Size;
 
                    Size margin = WorkflowTheme.CurrentTheme.AmbientTheme.Margin;
 
                    smartTagRectangle.X = rectangle.Left - margin.Width / 2; 
                    smartTagRectangle.Y = rectangle.Top - margin.Height / 2;
                    smartTagRectangle.Width = imageSize.Width + glyphSize.Width / 2 + 3 * margin.Width; 
                    smartTagRectangle.Height = imageSize.Height + margin.Height;
                }

                return smartTagRectangle; 
            }
 
            public override bool CanBeActivated 
            {
                get 
                {
                    return true;
                }
            } 

            protected override void OnPaint(Graphics graphics, bool activated, AmbientTheme ambientTheme, ActivityDesigner designer) 
            { 
                Rectangle activatedBounds = GetBounds(designer, true);
 
                bool formShown = false;//if the drop down form is shown, draw the arrow up
                if (Form.ActiveForm != null && Form.ActiveForm.GetType().FullName.Equals(typeof(ItemPalette).FullName + "+Palette", StringComparison.Ordinal))
                    formShown = (Form.ActiveForm.Location == designer.PointToScreen(new Point(activatedBounds.Left, activatedBounds.Bottom)));
 
                //work around: This is in order to show the smarttag activated when the drop down is shown but cursor leaves the active area of glyph
                if (!activated) 
                { 
                    if (this.activeDesigner != null)
                    { 
                        activated = true;
                    }
                    else if (Form.ActiveForm != null && Form.ActiveForm.GetType().FullName.Equals(typeof(ItemPalette).FullName + "+Palette", StringComparison.Ordinal))
                    { 
                        activated = formShown;
                    } 
                } 

                graphics.FillRectangle(WorkflowTheme.CurrentTheme.AmbientTheme.BackgroundBrush, activatedBounds); 
                using (Brush transparentSelectionBrush = new SolidBrush(Color.FromArgb(50, WorkflowTheme.CurrentTheme.AmbientTheme.SelectionForeColor)))
                    graphics.FillRectangle(transparentSelectionBrush, activatedBounds);
                graphics.DrawRectangle(SystemPens.ControlDarkDark, activatedBounds);
 
                //Draw the image
                Image image = designer.Image; 
                image = (designer.Image == null) ? SmartTag.defaultImage : image; 

                Size glyphSize = WorkflowTheme.CurrentTheme.AmbientTheme.GlyphSize; 
                Size imageSize = designer.SmartTagRectangle.Size;

                Size margin = WorkflowTheme.CurrentTheme.AmbientTheme.Margin;
 
                Rectangle imageRectangle = activatedBounds;
                imageRectangle.X += margin.Width / 2; 
                imageRectangle.Y += margin.Height / 2; 
                imageRectangle.Size = imageSize;
                ActivityDesignerPaint.DrawImage(graphics, image, imageRectangle, DesignerContentAlignment.Center); 

                //Draw the drop down indicator
                Rectangle dropDownRectangle = activatedBounds;
                dropDownRectangle.X += imageSize.Width + 3 * margin.Width / 2; 
                dropDownRectangle.Y += margin.Height / 2;
                dropDownRectangle.Width = glyphSize.Width / 2; 
                dropDownRectangle.Height -= glyphSize.Height / 4; 
                using (GraphicsPath graphicsPath = ActivityDesignerPaint.GetScrollIndicatorPath(dropDownRectangle, ScrollButton.Down))
                { 
                    graphics.FillPath(Brushes.Black, graphicsPath);
                    graphics.DrawPath(Pens.Black, graphicsPath);
                }
            } 

            protected override void OnActivate(ActivityDesigner designer) 
            { 
                if (designer.SmartTagVerbs.Count > 0)
                { 
                    this.activeDesigner = designer;
                    Rectangle bounds = GetBounds(designer, true);
                    this.activeDesigner.OnShowSmartTagVerbs(new Point(bounds.Left, bounds.Bottom + 1));
                    this.activeDesigner = null; 
                }
            } 
 
            internal ActivityDesigner ActiveDesigner
            { 
                get
                {
                    return this.activeDesigner;
                } 
            }
        } 
        #endregion 
    }
    #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