WorkflowViewElement.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / Tools / System.Activities.Presentation / System / Activities / Presentation / WorkflowViewElement.cs / 1407647 / WorkflowViewElement.cs

                            //---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------

 

namespace System.Activities.Presentation 
{ 
    using System.Activities.Presentation.Model;
    using System.Activities.Presentation.Services; 
    using System.Activities.Presentation.View;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics.CodeAnalysis; 
    using System.Globalization;
    using System.Runtime; 
    using System.Windows; 
    using System.Windows.Automation.Peers;
    using System.Windows.Controls; 
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Controls.Primitives;
    using System.Windows.Data; 
    using System.Timers;
    using System.Windows.Threading; 
    using System.Text; 

    // This is the base class of all things visual that are associated with ModelItems. 
    // e.g state designer, workflowelement designer, activity designe etc.
    // This provides access to the ModelItem attached to it,  and the EditingContext.
    public class WorkflowViewElement : ContentControl, ICompositeViewEvents
    { 
        public static readonly DependencyProperty ModelItemProperty =
            DependencyProperty.Register("ModelItem", typeof(ModelItem), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(WorkflowViewElement.OnModelItemChanged))); 
        public static readonly DependencyProperty ContextProperty = 
            DependencyProperty.Register("Context", typeof(EditingContext), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(WorkflowViewElement.OnContextChanged)));
        public static readonly DependencyProperty ExpandStateProperty = 
            DependencyProperty.Register("ExpandState", typeof(bool), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(true, new PropertyChangedCallback(WorkflowViewElement.OnExpandStateChanged)));
        public static readonly DependencyProperty PinStateProperty =
            DependencyProperty.Register("PinState", typeof(bool), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(WorkflowViewElement.OnPinStateChanged)));
        public static readonly DependencyProperty ShowExpandedProperty = 
            DependencyProperty.Register("ShowExpanded", typeof(bool), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(WorkflowViewElement.OnShowExpandedChanged)));
        internal readonly static DependencyProperty IsRootDesignerProperty = 
            DependencyProperty.Register("IsRootDesigner", typeof(bool), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(false)); 
        static readonly DependencyProperty IsReadOnlyProperty =
            DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(WorkflowViewElement.OnReadOnlyChanged))); 

        const string ExpandViewStateKey = "IsExpanded";
        internal const string PinnedViewStateKey = "IsPinned";
        Timer breadCrumbTimer; 
        int lastMouseButtonDownTimeStamp;
 
        static void OnExpandStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
        {
            WorkflowViewElement viewElement = obj as WorkflowViewElement; 
            viewElement.OnExpandStateChanged((bool)e.NewValue);
        }

        static void OnPinStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
        {
            WorkflowViewElement viewElement = obj as WorkflowViewElement; 
            viewElement.OnPinStateChanged((bool)e.NewValue); 
        }
 

        static void OnContextChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            WorkflowViewElement viewElement = obj as WorkflowViewElement; 
            viewElement.OnContextChanged();
        } 
 
        static void OnShowExpandedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        { 
            WorkflowViewElement viewElement = obj as WorkflowViewElement;
            viewElement.OnShowExpandedChanged((bool)e.NewValue);
        }
 
        static void OnReadOnlyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        { 
            WorkflowViewElement viewElement = obj as WorkflowViewElement; 
            viewElement.OnReadOnlyChanged((bool)e.NewValue);
        } 

        protected virtual void OnShowExpandedChanged(bool newValue)
        {
        } 

        protected virtual void OnReadOnlyChanged(bool isReadOnly) 
        { 
        }
 
        internal void ForceCollapse()
        {
            this.ExpandState = false;
            if (this.Designer.ShouldExpandAll) 
            {
                this.PinState = true; 
            } 
        }
 
        void OnContextChanged()
        {
            //Setting the binding here so that we have a handle to DesignerView.
            SetShowExpandedBindings(); 
        }
 
        void OnExpandStateChanged(bool newValue) 
        {
            if (this.ModelItem != null && this.Context != null) 
            {
                this.ViewStateService.StoreViewState(this.ModelItem, ExpandViewStateKey, newValue);
            }
        } 

        void OnPinStateChanged(bool newValue) 
        { 
            if (this.ModelItem != null && this.Context != null)
            { 
                this.ViewStateService.StoreViewState(this.ModelItem, WorkflowViewElement.PinnedViewStateKey, newValue);
            }
        }
 
        bool isMouseDown = false;
        Point lastMouseDownPoint; 
        UIElement lastActivationElement; 
        List compositeViews;
        ICompositeView defaultCompositeView; 
        bool selectionToggledWithCtrlDown = false;

        public WorkflowViewElement()
        { 
            this.Collapsible = true;
            this.IsAncestorOfRootDesigner = false; 
 
            this.Loaded += (sender, eventArgs) =>
                { 
                    this.breadCrumbTimer = new Timer(2000);
                    this.breadCrumbTimer.Elapsed += new ElapsedEventHandler(OnBreadCrumbTimerElapsed);
                    this.breadCrumbTimer.AutoReset = false;
                    this.lastActivationElement = null; 
                    this.SetValue(CutCopyPasteHelper.ChildContainersProperty, null);
                    if (this.ModelItem != null) 
                    { 
                        ((IModelTreeItem)this.ModelItem).SetCurrentView(this);
                    } 

                    //Get the ExpandState from ViewState.
                    if (this.ModelItem != null)
                    { 
                        object expandCollapseViewState = this.ViewStateService.RetrieveViewState(this.ModelItem, ExpandViewStateKey);
                        object pinViewState = this.ViewStateService.RetrieveViewState(this.ModelItem, WorkflowViewElement.PinnedViewStateKey); 
                        if (expandCollapseViewState != null) 
                        {
                            this.ExpandState = (bool)expandCollapseViewState; 
                        }
                        if (pinViewState != null)
                        {
                            this.PinState = (bool)pinViewState; 
                        }
                    } 
                    this.UseLayoutRounding = true; 
                };
 
            this.Unloaded += (sender, eventArgs) =>
                {
                    Fx.Assert(this.breadCrumbTimer != null, "The timer should not be null.");
                    this.breadCrumbTimer.Elapsed -= new ElapsedEventHandler(OnBreadCrumbTimerElapsed); 
                    this.breadCrumbTimer.Close();
                }; 
        } 

        protected override void OnInitialized(EventArgs e) 
        {
            base.OnInitialized(e);

            Binding readOnlyBinding = new Binding(); 
            readOnlyBinding.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DesignerView), 1);
            readOnlyBinding.Path = new PropertyPath(DesignerView.IsReadOnlyProperty); 
            readOnlyBinding.Mode = BindingMode.OneWay; 
            this.SetBinding(IsReadOnlyProperty, readOnlyBinding);
        } 

        void SetShowExpandedBindings()
        {
            MultiBinding multiBinding = new MultiBinding(); 
            //Bind to ModelItem
            Binding modelItemBinding = new Binding(); 
            modelItemBinding.Source = this; 
            modelItemBinding.Path = new PropertyPath(WorkflowViewElement.ModelItemProperty);
            //Bind to IsRootDesigner 
            Binding isRootDesignerBinding = new Binding();
            isRootDesignerBinding.Source = this;
            isRootDesignerBinding.Path = new PropertyPath(WorkflowViewElement.IsRootDesignerProperty);
            //Bind to DesignerView.ExpandAll 
            Binding expandAllBinding = new Binding();
            DesignerView view = this.Context.Services.GetService(); 
            expandAllBinding.Source = view; 
            expandAllBinding.Path = new PropertyPath(DesignerView.ShouldExpandAllProperty);
            //Bind to DesignerView.CollapseAll 
            Binding collapseAllBinding = new Binding();
            collapseAllBinding.Source = view;
            collapseAllBinding.Path = new PropertyPath(DesignerView.ShouldCollapseAllProperty);
            //Bind to ExpandState 
            Binding expandStateBinding = new Binding();
            expandStateBinding.Source = this; 
            expandStateBinding.Path = new PropertyPath(WorkflowViewElement.ExpandStateProperty); 
            //Bind to PinState
            Binding pinStateBinding = new Binding(); 
            pinStateBinding.Source = this;
            pinStateBinding.Path = new PropertyPath(WorkflowViewElement.PinStateProperty);
            //Bind to self
            Binding selfBinding = new Binding(); 
            selfBinding.Source = this;
            //Bind to container (to recalculate on drag-drop.) 
            Binding containerBinding = new Binding(); 
            containerBinding.Source = this;
            containerBinding.Path = new PropertyPath(DragDropHelper.DragSourceProperty); 
            multiBinding.Bindings.Add(modelItemBinding);
            multiBinding.Bindings.Add(isRootDesignerBinding);
            multiBinding.Bindings.Add(expandAllBinding);
            multiBinding.Bindings.Add(collapseAllBinding); 
            multiBinding.Bindings.Add(expandStateBinding);
            multiBinding.Bindings.Add(pinStateBinding); 
            multiBinding.Bindings.Add(selfBinding); 
            multiBinding.Bindings.Add(containerBinding);
 
            multiBinding.Mode = BindingMode.OneWay;
            multiBinding.Converter = new ShowExpandedMultiValueConverter();
            BindingOperations.SetBinding(this, WorkflowViewElement.ShowExpandedProperty, multiBinding );
        } 

        [Fx.Tag.KnownXamlExternal] 
        public EditingContext Context 
        {
            get { return (EditingContext)GetValue(ContextProperty); } 
            set { SetValue(ContextProperty, value); }
        }

        public bool ExpandState 
        {
            get { return (bool)GetValue(ExpandStateProperty); } 
            set { SetValue(ExpandStateProperty, value); } 
        }
 
        public bool PinState
        {
            get { return (bool)GetValue(PinStateProperty); }
            set { SetValue(PinStateProperty, value); } 
        }
 
        //This guides us whether to show the expand collapse button for this ViewElement or not. 
        public bool Collapsible
        { 
            get;
            set;
        }
 
        public bool IsRootDesigner
        { 
            get { return (bool)GetValue(IsRootDesignerProperty); } 
            internal set { SetValue(IsRootDesignerProperty, value); }
        } 

        internal bool IsAncestorOfRootDesigner
        {
            get; 
            set;
        } 
 
        public bool ShowExpanded
        { 
            get { return (bool)GetValue(ShowExpandedProperty); }
        }

        internal bool DoesParentAlwaysExpandChild() 
        {
            return ViewUtilities.DoesParentAlwaysExpandChildren(this.ModelItem, this.Context); 
        } 

        internal bool DoesParentAlwaysCollapseChildren() 
        {
            return ViewUtilities.DoesParentAlwaysCollapseChildren(this.ModelItem, this.Context);
        }
 

        [Fx.Tag.KnownXamlExternal] 
        public ModelItem ModelItem 
        {
            get { return (ModelItem)GetValue(ModelItemProperty); } 
            set { SetValue(ModelItemProperty, value); }
        }

        protected bool IsReadOnly 
        {
            get { return (bool)GetValue(IsReadOnlyProperty); } 
            private set { SetValue(IsReadOnlyProperty, value); } 
        }
 
        internal ICompositeView ActiveCompositeView
        {
            get
            { 
                if (!this.ShowExpanded)
                { 
                    return null; 
                }
                ICompositeView activeContainer = null; 
                if (null != this.compositeViews && null != this.lastActivationElement)
                {
                    activeContainer = this.compositeViews.Find(p =>
                        { 
                            Visual visual = p as Visual;
                            return (null != visual && 
                                visual == this.lastActivationElement.FindCommonVisualAncestor(visual)); 
                        });
                } 
                activeContainer = activeContainer ?? this.DefaultCompositeView;

                System.Diagnostics.Debug.WriteLine(string.Format(
                    CultureInfo.InvariantCulture, 
                    "Active ICompositeView in '{0}' is '{1}'",
                    this.GetType().Name, activeContainer == null ? "" : activeContainer.GetHashCode().ToString(CultureInfo.InvariantCulture))); 
 
                return activeContainer;
            } 
        }

        // useful shortcuts for things we know we will be using a lot.
        // Shortcut to viewservice in editingcontext.services 
        protected internal ViewService ViewService
        { 
            get 
            {
                Fx.Assert(this.Context != null, "Context should not be null "); 
                ViewService viewService = this.Context.Services.GetService();
                Fx.Assert(viewService != null, "View service should never be null if we are in a valid view tree");
                return viewService;
            } 
        }
 
        // Shortcut to ViewStateService in editingcontext.services 
        protected internal ViewStateService ViewStateService
        { 
            get
            {
                ViewStateService viewStateService = this.Context.Services.GetService();
                Fx.Assert(viewStateService != null, "ViewState service should never be null if we are in a valid view tree"); 
                return viewStateService;
            } 
        } 

        protected internal DesignerView Designer 
        {
            get
            {
                DesignerView designer = this.Context.Services.GetService(); 
                Fx.Assert(designer != null, "DesignerView service should never be null if we are in a valid state");
                return designer; 
            } 
        }
 
        protected IList CompositeViews
        {
            get { return this.compositeViews; }
        } 

        protected ICompositeView DefaultCompositeView 
        { 
            get { return this.defaultCompositeView; }
        } 

        protected virtual string GetAutomationIdMemberName()
        {
            return null; 
        }
 
        protected virtual string GetAutomationHelpText() 
        {
            return string.Empty; 
        }

        protected override AutomationPeer OnCreateAutomationPeer()
        { 
            return new WorkflowViewElementAutomationPeer(this);
        } 
 

        public void RegisterDefaultCompositeView(ICompositeView container) 
        {
            if (null == container)
            {
                throw FxTrace.Exception.AsError(new ArgumentNullException("container")); 
            }
 
            this.defaultCompositeView = container; 

            System.Diagnostics.Debug.WriteLine(string.Format( 
                CultureInfo.InvariantCulture,
                "Default ICompositeView of type '{0}' for '{1}' loaded. hashcode = {2}",
                this.defaultCompositeView.GetType().Name, this.GetType().Name, this.defaultCompositeView.GetHashCode()));
        } 

        public void UnregisterDefaultCompositeView(ICompositeView container) 
        { 
            if (null == container)
            { 
                throw FxTrace.Exception.AsError(new ArgumentNullException("container"));
            }

            if (object.Equals(this.defaultCompositeView, container)) 
            {
                this.defaultCompositeView = null; 
            } 
        }
 
        public void RegisterCompositeView(ICompositeView container)
        {
            if (null == container)
            { 
                throw FxTrace.Exception.AsError(new ArgumentNullException("container"));
            } 
 
            if (null == this.CompositeViews)
            { 
                this.compositeViews = new List();
            }
            if (!this.compositeViews.Contains(container))
            { 
                System.Diagnostics.Debug.WriteLine(string.Format(
                    CultureInfo.InvariantCulture, 
                    "ICompositeView of type '{0}' for '{1}' loaded. hashcode = {2}", 
                    container.GetType().Name, this.GetType().Name, container.GetHashCode()));
 
                this.compositeViews.Add(container);
            }
        }
 
        public void UnregisterCompositeView(ICompositeView container)
        { 
            if (null == container) 
            {
                throw FxTrace.Exception.AsError(new ArgumentNullException("container")); 
            }

            if (null != this.compositeViews && this.compositeViews.Contains(container))
            { 
                System.Diagnostics.Debug.WriteLine(string.Format(
                    CultureInfo.InvariantCulture, 
                    "ICompositeView of type '{0}' for '{1}' unloaded", 
                    container.GetType().Name, this.GetType().Name));
 
                this.compositeViews.Remove(container);
                if (0 == this.compositeViews.Count)
                {
                    this.compositeViews = null; 
                }
            } 
        } 

 
        protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
        {
            DesignerView designerView = this.Context.Services.GetService();
            if (!e.Handled && this.ModelItem != null && !designerView.IsMultipleSelectionMode) 
            {
                Selection selection = this.Context.Items.GetValue(); 
                //update selection when following conditions apply: 
                //1. We're not trying to do multiselect using mouse + ctrl key.
                //2. current primary selection is different than this.ModelItem 
                bool becomesSelection = !this.selectionToggledWithCtrlDown && selection.PrimarySelection != this.ModelItem;

                //When there is only one selected model item, we want to change the selection when we tab into other items.
                if (becomesSelection) 
                {
                    Selection.SelectOnly(this.Context, this.ModelItem); 
                } 

                System.Diagnostics.Debug.WriteLine( 
                    string.Format(CultureInfo.InvariantCulture, "{0} ) WorkflowViewElement.OnGotKeyboardFocus ({1}, selection: {2}, becomesSelection {3}, raisedBy {4})",
                    DateTime.Now.ToLocalTime(), this.GetType().Name, selection.SelectionCount, becomesSelection, e.OriginalSource));

                //do not override last activation element if we get a reference to this (this will be passed as original source 
                //whenever focus is set manualy - by direct call to Keyboard.SetFocus)
                if (!object.Equals(this, e.OriginalSource)) 
                { 
                    this.lastActivationElement = e.OriginalSource as UIElement;
                } 
                e.Handled = true;
            }
            else
            { 
                this.lastActivationElement = null;
            } 
            base.OnGotKeyboardFocus(e); 
        }
 
        protected virtual void OnModelItemChanged(object newItem)
        {
        }
 
        protected virtual void OnContextMenuLoaded(ContextMenu menu)
        { 
        } 

        void MakeRootDesigner() 
        {
            DesignerView designerView = this.Context.Services.GetService();
            if (!this.Equals(designerView.RootDesigner))
            { 
                designerView.MakeRootDesigner(this.ModelItem);
                this.isMouseDown = false; 
            } 
        }
 
        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            this.lastMouseButtonDownTimeStamp = e.Timestamp;
            bool shouldSetFocus = false; 
            bool shouldUpdateLastActivationPoint = false;
            if (this.ModelItem == null) 
            { 
                return;
            } 
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                this.isMouseDown = true;
                this.lastMouseDownPoint = e.GetPosition(this); 
                if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
                { 
                    this.selectionToggledWithCtrlDown = true; 
                }
                else 
                {
                    this.CaptureMouse();
                }
                shouldSetFocus = Keyboard.FocusedElement != this; 
                e.Handled = true;
                shouldUpdateLastActivationPoint = true; 
            } 
            if (e.LeftButton == MouseButtonState.Pressed && e.ClickCount == 2 && this.Designer.lastClickedDesigner == this)
            { 
                this.MakeRootDesigner();
                Mouse.Capture(null);
                e.Handled = true;
            } 
            if (e.RightButton == MouseButtonState.Pressed)
            { 
                this.lastMouseDownPoint = e.GetPosition(this); 
                shouldSetFocus = Keyboard.FocusedElement != this;
                e.Handled = true; 
                shouldUpdateLastActivationPoint = true;
            }

            System.Diagnostics.Debug.WriteLine( 
                string.Format(CultureInfo.InvariantCulture, "{0} ) WorkflowViewElement.OnMouseDown ({1}, shouldSetFocus {2}, mouseCaptured {3}, raisedBy {4})",
                DateTime.Now.ToLocalTime(), this.GetType().Name, shouldSetFocus, this.IsMouseCaptured, e.OriginalSource)); 
 
            base.OnMouseDown(e);
 
            if (shouldSetFocus)
            {
                System.Diagnostics.Debug.WriteLine(
                    string.Format(CultureInfo.InvariantCulture, "{0} ) WorkflowViewElement.OnMouseDown.SetFocus ({1})", 
                    DateTime.Now.ToLocalTime(), this.GetType().Name));
                //attempt to set focused and keyboard focused element to new designer 
                Keyboard.Focus(this); 
            }
 
            //Change the selection after setting the focus because of CSDMain#130034.
            if (this.selectionToggledWithCtrlDown)
            {
                Selection.Toggle(this.Context, this.ModelItem); 
            }
            else 
            { 
                Selection.SelectOnly(this.Context, this.ModelItem);
            } 

            this.selectionToggledWithCtrlDown = false;

            if (shouldUpdateLastActivationPoint) 
            {
                this.lastActivationElement = e.OriginalSource as UIElement; 
            } 

            if (e.LeftButton == MouseButtonState.Pressed) 
            {
                this.Designer.lastClickedDesigner = this;
            }
        } 

        protected override void OnMouseMove(MouseEventArgs e) 
        { 
            // if model item is removed, uncapture mouse and return
            if (this.ModelItem != null && this.ModelItem != this.ModelItem.Root && this.ModelItem.Parent == null) 
            {
                if (this.IsMouseCaptured)
                {
                    Mouse.Capture(null); 
                }
                return; 
            } 

            if (e.LeftButton == MouseButtonState.Pressed && 
                this.isMouseDown &&
                this.ModelItem != null &&
                e.Timestamp - this.lastMouseButtonDownTimeStamp > 100 &&
                !(this.ModelItem == this.ModelItem.Root)) 
            {
                //get new position 
                Point newPosition = e.GetPosition(this); 
                //calculate distance
                Vector difference = newPosition - this.lastMouseDownPoint; 
                if (Math.Abs(difference.X) > SystemParameters.MinimumHorizontalDragDistance ||
                    Math.Abs(difference.Y) > SystemParameters.MinimumVerticalDragDistance)
                {
                    //if mouse is caputured - release capture, drag&drop infrastructure will take care now for tracking mouse move 
                    if (this.IsMouseCaptured)
                    { 
                        Mouse.Capture(null); 
                        StartDragging();
                    } 

                    this.isMouseDown = false;
                    e.Handled = true;
                } 
            }
            base.OnMouseMove(e); 
        } 

        protected override void OnMouseUp(MouseButtonEventArgs e) 
        {
            System.Diagnostics.Debug.WriteLine(
                CultureInfo.InvariantCulture,
                string.Format(CultureInfo.CurrentUICulture, "{0} ) WorkflowViewElement.OnMouseUp ({1}, mouseCaptured {2})", 
                DateTime.Now.ToLocalTime(), this.GetType().Name, this.IsMouseCaptured));
 
            if (this.isMouseDown) 
            {
                if (this.IsMouseCaptured) 
                {
                    Mouse.Capture(null);
                }
                this.isMouseDown = false; 
                e.Handled = true;
            } 
            base.OnMouseUp(e); 
        }
 
        void OnBreadCrumbTimerElapsed(object sender, ElapsedEventArgs e)
        {
            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
                { 
                    this.breadCrumbTimer.Stop();
                    this.MakeRootDesigner(); 
                })); 
        }
 
        void OnDrag(DragEventArgs e)
        {
            if (!e.Handled)
            { 
                e.Effects = DragDropEffects.None;
                e.Handled = true; 
            } 
        }
 
        // This is to set the cursor to the forbidden icon when dragging to the designer.
        // It doesn't affect the drag-drop behavior of components that have AllowDrop == ture within the designer.
        protected override void OnDragEnter(DragEventArgs e)
        { 
            this.OnDrag(e);
            base.OnDragEnter(e); 
        } 

        // This is to set the cursor to the forbidden icon when dragging within the designer. 
        // It doesn't affect the drag-drop behavior of components that have AllowDrop == ture within the designer.
        protected override void OnDragOver(DragEventArgs e)
        {
            this.OnDrag(e); 
            base.OnDragOver(e);
        } 
 
        protected override void OnPreviewDragEnter(DragEventArgs e)
        { 
            if (this.ShowExpanded == false)
            {
                this.breadCrumbTimer.Start();
            } 
            base.OnPreviewDragEnter(e);
        } 
 
        protected override void OnPreviewDragLeave(DragEventArgs e)
        { 
            this.breadCrumbTimer.Stop();
            base.OnPreviewDragLeave(e);
        }
 
        protected override void OnPreviewMouseUp(MouseButtonEventArgs e)
        { 
            this.breadCrumbTimer.Stop(); 
            base.OnPreviewMouseUp(e);
        } 

        static void OnModelItemChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            WorkflowViewElement viewElement = (WorkflowViewElement)dependencyObject; 
            viewElement.OnModelItemChanged(e.NewValue);
        } 
 
        void BeginDropAnimation(WorkflowViewElement target)
        { 
            DropAnimation opacityAnimation = new DropAnimation();
            target.BeginAnimation(FrameworkElement.OpacityProperty, opacityAnimation);
        }
 
        [SuppressMessage(FxCop.Category.Design, FxCop.Rule.DoNotCatchGeneralExceptionTypes,
            Justification = "Catching all exceptions to avoid VS Crash.")] 
        [SuppressMessage("Reliability", "Reliability108", 
            Justification = "Catching all exceptions to avoid VS crash.")]
 
        void StartDragging()
        {

            try 
            {
                ModelItem movingModelItem = this.ModelItem; 
                ICompositeView sourceContainer = (ICompositeView)DragDropHelper.GetCompositeView(this); 
                if (sourceContainer != null)
                { 
                    using (ModelEditingScope editingScope = movingModelItem.BeginEdit(SR.MoveEditingScopeDescription))
                    {
                        DragDropEffects executedDragDropEffect = DragDropHelper.DoDragMove(this, this.lastMouseDownPoint);
                        //once drag drop is done make sure the CompositeView is notified of the change in data 
                        if (executedDragDropEffect == DragDropEffects.Move)
                        { 
                            sourceContainer.OnItemMoved(movingModelItem); 

                            UIElement movedElement = (UIElement)(movingModelItem.View); 
                            BeginDropAnimation((WorkflowViewElement)movedElement);
                        }
                        editingScope.Complete();
                    } 
                }
            } 
            catch (Exception e) 
            {
                ErrorReporting.ShowErrorMessage(e.Message); 
            }

        }
 
        internal void NotifyContextMenuLoaded(ContextMenu menu)
        { 
            if (null != menu) 
            {
                OnContextMenuLoaded(menu); 
            }
        }

        class WorkflowViewElementAutomationPeer : UIElementAutomationPeer 
        {
            WorkflowViewElement owner; 
 
            public WorkflowViewElementAutomationPeer(WorkflowViewElement owner)
                : base(owner) 
            {
                this.owner = owner;
            }
 
            protected override AutomationControlType GetAutomationControlTypeCore()
            { 
                return AutomationControlType.Custom; 
            }
 

            protected override string GetAutomationIdCore()
            {
                string automationId = this.GetClassNameCore(); 
                string automationIdVariablePartMemberName = owner.GetAutomationIdMemberName();
                if (!string.IsNullOrEmpty(automationIdVariablePartMemberName)) 
                { 
                    ModelItem modelItem = this.owner.ModelItem;
                    string variablePartOfAutomationId = string.Empty; 
                    if (modelItem != null)
                    {
                        ModelProperty property = modelItem.Properties[automationIdVariablePartMemberName];
                        Fx.Assert(property != null, "property to use for Automation ID variable part missing ? are you using the right property Name?"); 
                        if (property.Value != null)
                        { 
                            variablePartOfAutomationId = property.Value.GetCurrentValue().ToString(); 
                        }
                    } 
                    automationId = variablePartOfAutomationId + "(" + this.GetClassNameCore() + ")";
                }
                return automationId;
            } 

            protected override string GetNameCore() 
            { 
                Type itemType = null;
                if (this.owner.ModelItem != null) 
                {
                    itemType = this.owner.ModelItem.ItemType;
                }
                else 
                {
                    itemType = this.owner.GetType(); 
                } 

                if (itemType.IsGenericType) 
                {
                    //append the argument types for generic types
                    //we expect the single level of generic is sufficient for the screen reader, so we're no going into
                    //nesting of generic types 
                    Type[] argumentTypes = itemType.GetGenericArguments();
                    StringBuilder name = new StringBuilder(itemType.Name); 
                    name.Append('['); 
                    foreach (Type argument in argumentTypes)
                    { 
                        name.Append(argument.Name);
                        name.Append(',');
                    }
                    name.Replace(',', ']', name.Length - 1, 1); 
                    return name.ToString();
                } 
                else 
                {
                    return itemType.Name; 
                }
            }

            protected override string GetHelpTextCore() 
            {
                return this.owner.GetAutomationHelpText(); 
            } 

            protected override string GetClassNameCore() 
            {
                return this.owner.GetType().Name;
            }
        } 
    }
 
} 

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

 

namespace System.Activities.Presentation 
{ 
    using System.Activities.Presentation.Model;
    using System.Activities.Presentation.Services; 
    using System.Activities.Presentation.View;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics.CodeAnalysis; 
    using System.Globalization;
    using System.Runtime; 
    using System.Windows; 
    using System.Windows.Automation.Peers;
    using System.Windows.Controls; 
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Controls.Primitives;
    using System.Windows.Data; 
    using System.Timers;
    using System.Windows.Threading; 
    using System.Text; 

    // This is the base class of all things visual that are associated with ModelItems. 
    // e.g state designer, workflowelement designer, activity designe etc.
    // This provides access to the ModelItem attached to it,  and the EditingContext.
    public class WorkflowViewElement : ContentControl, ICompositeViewEvents
    { 
        public static readonly DependencyProperty ModelItemProperty =
            DependencyProperty.Register("ModelItem", typeof(ModelItem), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(WorkflowViewElement.OnModelItemChanged))); 
        public static readonly DependencyProperty ContextProperty = 
            DependencyProperty.Register("Context", typeof(EditingContext), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(WorkflowViewElement.OnContextChanged)));
        public static readonly DependencyProperty ExpandStateProperty = 
            DependencyProperty.Register("ExpandState", typeof(bool), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(true, new PropertyChangedCallback(WorkflowViewElement.OnExpandStateChanged)));
        public static readonly DependencyProperty PinStateProperty =
            DependencyProperty.Register("PinState", typeof(bool), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(WorkflowViewElement.OnPinStateChanged)));
        public static readonly DependencyProperty ShowExpandedProperty = 
            DependencyProperty.Register("ShowExpanded", typeof(bool), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(WorkflowViewElement.OnShowExpandedChanged)));
        internal readonly static DependencyProperty IsRootDesignerProperty = 
            DependencyProperty.Register("IsRootDesigner", typeof(bool), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(false)); 
        static readonly DependencyProperty IsReadOnlyProperty =
            DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(WorkflowViewElement), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(WorkflowViewElement.OnReadOnlyChanged))); 

        const string ExpandViewStateKey = "IsExpanded";
        internal const string PinnedViewStateKey = "IsPinned";
        Timer breadCrumbTimer; 
        int lastMouseButtonDownTimeStamp;
 
        static void OnExpandStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
        {
            WorkflowViewElement viewElement = obj as WorkflowViewElement; 
            viewElement.OnExpandStateChanged((bool)e.NewValue);
        }

        static void OnPinStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
        {
            WorkflowViewElement viewElement = obj as WorkflowViewElement; 
            viewElement.OnPinStateChanged((bool)e.NewValue); 
        }
 

        static void OnContextChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            WorkflowViewElement viewElement = obj as WorkflowViewElement; 
            viewElement.OnContextChanged();
        } 
 
        static void OnShowExpandedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        { 
            WorkflowViewElement viewElement = obj as WorkflowViewElement;
            viewElement.OnShowExpandedChanged((bool)e.NewValue);
        }
 
        static void OnReadOnlyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        { 
            WorkflowViewElement viewElement = obj as WorkflowViewElement; 
            viewElement.OnReadOnlyChanged((bool)e.NewValue);
        } 

        protected virtual void OnShowExpandedChanged(bool newValue)
        {
        } 

        protected virtual void OnReadOnlyChanged(bool isReadOnly) 
        { 
        }
 
        internal void ForceCollapse()
        {
            this.ExpandState = false;
            if (this.Designer.ShouldExpandAll) 
            {
                this.PinState = true; 
            } 
        }
 
        void OnContextChanged()
        {
            //Setting the binding here so that we have a handle to DesignerView.
            SetShowExpandedBindings(); 
        }
 
        void OnExpandStateChanged(bool newValue) 
        {
            if (this.ModelItem != null && this.Context != null) 
            {
                this.ViewStateService.StoreViewState(this.ModelItem, ExpandViewStateKey, newValue);
            }
        } 

        void OnPinStateChanged(bool newValue) 
        { 
            if (this.ModelItem != null && this.Context != null)
            { 
                this.ViewStateService.StoreViewState(this.ModelItem, WorkflowViewElement.PinnedViewStateKey, newValue);
            }
        }
 
        bool isMouseDown = false;
        Point lastMouseDownPoint; 
        UIElement lastActivationElement; 
        List compositeViews;
        ICompositeView defaultCompositeView; 
        bool selectionToggledWithCtrlDown = false;

        public WorkflowViewElement()
        { 
            this.Collapsible = true;
            this.IsAncestorOfRootDesigner = false; 
 
            this.Loaded += (sender, eventArgs) =>
                { 
                    this.breadCrumbTimer = new Timer(2000);
                    this.breadCrumbTimer.Elapsed += new ElapsedEventHandler(OnBreadCrumbTimerElapsed);
                    this.breadCrumbTimer.AutoReset = false;
                    this.lastActivationElement = null; 
                    this.SetValue(CutCopyPasteHelper.ChildContainersProperty, null);
                    if (this.ModelItem != null) 
                    { 
                        ((IModelTreeItem)this.ModelItem).SetCurrentView(this);
                    } 

                    //Get the ExpandState from ViewState.
                    if (this.ModelItem != null)
                    { 
                        object expandCollapseViewState = this.ViewStateService.RetrieveViewState(this.ModelItem, ExpandViewStateKey);
                        object pinViewState = this.ViewStateService.RetrieveViewState(this.ModelItem, WorkflowViewElement.PinnedViewStateKey); 
                        if (expandCollapseViewState != null) 
                        {
                            this.ExpandState = (bool)expandCollapseViewState; 
                        }
                        if (pinViewState != null)
                        {
                            this.PinState = (bool)pinViewState; 
                        }
                    } 
                    this.UseLayoutRounding = true; 
                };
 
            this.Unloaded += (sender, eventArgs) =>
                {
                    Fx.Assert(this.breadCrumbTimer != null, "The timer should not be null.");
                    this.breadCrumbTimer.Elapsed -= new ElapsedEventHandler(OnBreadCrumbTimerElapsed); 
                    this.breadCrumbTimer.Close();
                }; 
        } 

        protected override void OnInitialized(EventArgs e) 
        {
            base.OnInitialized(e);

            Binding readOnlyBinding = new Binding(); 
            readOnlyBinding.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DesignerView), 1);
            readOnlyBinding.Path = new PropertyPath(DesignerView.IsReadOnlyProperty); 
            readOnlyBinding.Mode = BindingMode.OneWay; 
            this.SetBinding(IsReadOnlyProperty, readOnlyBinding);
        } 

        void SetShowExpandedBindings()
        {
            MultiBinding multiBinding = new MultiBinding(); 
            //Bind to ModelItem
            Binding modelItemBinding = new Binding(); 
            modelItemBinding.Source = this; 
            modelItemBinding.Path = new PropertyPath(WorkflowViewElement.ModelItemProperty);
            //Bind to IsRootDesigner 
            Binding isRootDesignerBinding = new Binding();
            isRootDesignerBinding.Source = this;
            isRootDesignerBinding.Path = new PropertyPath(WorkflowViewElement.IsRootDesignerProperty);
            //Bind to DesignerView.ExpandAll 
            Binding expandAllBinding = new Binding();
            DesignerView view = this.Context.Services.GetService(); 
            expandAllBinding.Source = view; 
            expandAllBinding.Path = new PropertyPath(DesignerView.ShouldExpandAllProperty);
            //Bind to DesignerView.CollapseAll 
            Binding collapseAllBinding = new Binding();
            collapseAllBinding.Source = view;
            collapseAllBinding.Path = new PropertyPath(DesignerView.ShouldCollapseAllProperty);
            //Bind to ExpandState 
            Binding expandStateBinding = new Binding();
            expandStateBinding.Source = this; 
            expandStateBinding.Path = new PropertyPath(WorkflowViewElement.ExpandStateProperty); 
            //Bind to PinState
            Binding pinStateBinding = new Binding(); 
            pinStateBinding.Source = this;
            pinStateBinding.Path = new PropertyPath(WorkflowViewElement.PinStateProperty);
            //Bind to self
            Binding selfBinding = new Binding(); 
            selfBinding.Source = this;
            //Bind to container (to recalculate on drag-drop.) 
            Binding containerBinding = new Binding(); 
            containerBinding.Source = this;
            containerBinding.Path = new PropertyPath(DragDropHelper.DragSourceProperty); 
            multiBinding.Bindings.Add(modelItemBinding);
            multiBinding.Bindings.Add(isRootDesignerBinding);
            multiBinding.Bindings.Add(expandAllBinding);
            multiBinding.Bindings.Add(collapseAllBinding); 
            multiBinding.Bindings.Add(expandStateBinding);
            multiBinding.Bindings.Add(pinStateBinding); 
            multiBinding.Bindings.Add(selfBinding); 
            multiBinding.Bindings.Add(containerBinding);
 
            multiBinding.Mode = BindingMode.OneWay;
            multiBinding.Converter = new ShowExpandedMultiValueConverter();
            BindingOperations.SetBinding(this, WorkflowViewElement.ShowExpandedProperty, multiBinding );
        } 

        [Fx.Tag.KnownXamlExternal] 
        public EditingContext Context 
        {
            get { return (EditingContext)GetValue(ContextProperty); } 
            set { SetValue(ContextProperty, value); }
        }

        public bool ExpandState 
        {
            get { return (bool)GetValue(ExpandStateProperty); } 
            set { SetValue(ExpandStateProperty, value); } 
        }
 
        public bool PinState
        {
            get { return (bool)GetValue(PinStateProperty); }
            set { SetValue(PinStateProperty, value); } 
        }
 
        //This guides us whether to show the expand collapse button for this ViewElement or not. 
        public bool Collapsible
        { 
            get;
            set;
        }
 
        public bool IsRootDesigner
        { 
            get { return (bool)GetValue(IsRootDesignerProperty); } 
            internal set { SetValue(IsRootDesignerProperty, value); }
        } 

        internal bool IsAncestorOfRootDesigner
        {
            get; 
            set;
        } 
 
        public bool ShowExpanded
        { 
            get { return (bool)GetValue(ShowExpandedProperty); }
        }

        internal bool DoesParentAlwaysExpandChild() 
        {
            return ViewUtilities.DoesParentAlwaysExpandChildren(this.ModelItem, this.Context); 
        } 

        internal bool DoesParentAlwaysCollapseChildren() 
        {
            return ViewUtilities.DoesParentAlwaysCollapseChildren(this.ModelItem, this.Context);
        }
 

        [Fx.Tag.KnownXamlExternal] 
        public ModelItem ModelItem 
        {
            get { return (ModelItem)GetValue(ModelItemProperty); } 
            set { SetValue(ModelItemProperty, value); }
        }

        protected bool IsReadOnly 
        {
            get { return (bool)GetValue(IsReadOnlyProperty); } 
            private set { SetValue(IsReadOnlyProperty, value); } 
        }
 
        internal ICompositeView ActiveCompositeView
        {
            get
            { 
                if (!this.ShowExpanded)
                { 
                    return null; 
                }
                ICompositeView activeContainer = null; 
                if (null != this.compositeViews && null != this.lastActivationElement)
                {
                    activeContainer = this.compositeViews.Find(p =>
                        { 
                            Visual visual = p as Visual;
                            return (null != visual && 
                                visual == this.lastActivationElement.FindCommonVisualAncestor(visual)); 
                        });
                } 
                activeContainer = activeContainer ?? this.DefaultCompositeView;

                System.Diagnostics.Debug.WriteLine(string.Format(
                    CultureInfo.InvariantCulture, 
                    "Active ICompositeView in '{0}' is '{1}'",
                    this.GetType().Name, activeContainer == null ? "" : activeContainer.GetHashCode().ToString(CultureInfo.InvariantCulture))); 
 
                return activeContainer;
            } 
        }

        // useful shortcuts for things we know we will be using a lot.
        // Shortcut to viewservice in editingcontext.services 
        protected internal ViewService ViewService
        { 
            get 
            {
                Fx.Assert(this.Context != null, "Context should not be null "); 
                ViewService viewService = this.Context.Services.GetService();
                Fx.Assert(viewService != null, "View service should never be null if we are in a valid view tree");
                return viewService;
            } 
        }
 
        // Shortcut to ViewStateService in editingcontext.services 
        protected internal ViewStateService ViewStateService
        { 
            get
            {
                ViewStateService viewStateService = this.Context.Services.GetService();
                Fx.Assert(viewStateService != null, "ViewState service should never be null if we are in a valid view tree"); 
                return viewStateService;
            } 
        } 

        protected internal DesignerView Designer 
        {
            get
            {
                DesignerView designer = this.Context.Services.GetService(); 
                Fx.Assert(designer != null, "DesignerView service should never be null if we are in a valid state");
                return designer; 
            } 
        }
 
        protected IList CompositeViews
        {
            get { return this.compositeViews; }
        } 

        protected ICompositeView DefaultCompositeView 
        { 
            get { return this.defaultCompositeView; }
        } 

        protected virtual string GetAutomationIdMemberName()
        {
            return null; 
        }
 
        protected virtual string GetAutomationHelpText() 
        {
            return string.Empty; 
        }

        protected override AutomationPeer OnCreateAutomationPeer()
        { 
            return new WorkflowViewElementAutomationPeer(this);
        } 
 

        public void RegisterDefaultCompositeView(ICompositeView container) 
        {
            if (null == container)
            {
                throw FxTrace.Exception.AsError(new ArgumentNullException("container")); 
            }
 
            this.defaultCompositeView = container; 

            System.Diagnostics.Debug.WriteLine(string.Format( 
                CultureInfo.InvariantCulture,
                "Default ICompositeView of type '{0}' for '{1}' loaded. hashcode = {2}",
                this.defaultCompositeView.GetType().Name, this.GetType().Name, this.defaultCompositeView.GetHashCode()));
        } 

        public void UnregisterDefaultCompositeView(ICompositeView container) 
        { 
            if (null == container)
            { 
                throw FxTrace.Exception.AsError(new ArgumentNullException("container"));
            }

            if (object.Equals(this.defaultCompositeView, container)) 
            {
                this.defaultCompositeView = null; 
            } 
        }
 
        public void RegisterCompositeView(ICompositeView container)
        {
            if (null == container)
            { 
                throw FxTrace.Exception.AsError(new ArgumentNullException("container"));
            } 
 
            if (null == this.CompositeViews)
            { 
                this.compositeViews = new List();
            }
            if (!this.compositeViews.Contains(container))
            { 
                System.Diagnostics.Debug.WriteLine(string.Format(
                    CultureInfo.InvariantCulture, 
                    "ICompositeView of type '{0}' for '{1}' loaded. hashcode = {2}", 
                    container.GetType().Name, this.GetType().Name, container.GetHashCode()));
 
                this.compositeViews.Add(container);
            }
        }
 
        public void UnregisterCompositeView(ICompositeView container)
        { 
            if (null == container) 
            {
                throw FxTrace.Exception.AsError(new ArgumentNullException("container")); 
            }

            if (null != this.compositeViews && this.compositeViews.Contains(container))
            { 
                System.Diagnostics.Debug.WriteLine(string.Format(
                    CultureInfo.InvariantCulture, 
                    "ICompositeView of type '{0}' for '{1}' unloaded", 
                    container.GetType().Name, this.GetType().Name));
 
                this.compositeViews.Remove(container);
                if (0 == this.compositeViews.Count)
                {
                    this.compositeViews = null; 
                }
            } 
        } 

 
        protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
        {
            DesignerView designerView = this.Context.Services.GetService();
            if (!e.Handled && this.ModelItem != null && !designerView.IsMultipleSelectionMode) 
            {
                Selection selection = this.Context.Items.GetValue(); 
                //update selection when following conditions apply: 
                //1. We're not trying to do multiselect using mouse + ctrl key.
                //2. current primary selection is different than this.ModelItem 
                bool becomesSelection = !this.selectionToggledWithCtrlDown && selection.PrimarySelection != this.ModelItem;

                //When there is only one selected model item, we want to change the selection when we tab into other items.
                if (becomesSelection) 
                {
                    Selection.SelectOnly(this.Context, this.ModelItem); 
                } 

                System.Diagnostics.Debug.WriteLine( 
                    string.Format(CultureInfo.InvariantCulture, "{0} ) WorkflowViewElement.OnGotKeyboardFocus ({1}, selection: {2}, becomesSelection {3}, raisedBy {4})",
                    DateTime.Now.ToLocalTime(), this.GetType().Name, selection.SelectionCount, becomesSelection, e.OriginalSource));

                //do not override last activation element if we get a reference to this (this will be passed as original source 
                //whenever focus is set manualy - by direct call to Keyboard.SetFocus)
                if (!object.Equals(this, e.OriginalSource)) 
                { 
                    this.lastActivationElement = e.OriginalSource as UIElement;
                } 
                e.Handled = true;
            }
            else
            { 
                this.lastActivationElement = null;
            } 
            base.OnGotKeyboardFocus(e); 
        }
 
        protected virtual void OnModelItemChanged(object newItem)
        {
        }
 
        protected virtual void OnContextMenuLoaded(ContextMenu menu)
        { 
        } 

        void MakeRootDesigner() 
        {
            DesignerView designerView = this.Context.Services.GetService();
            if (!this.Equals(designerView.RootDesigner))
            { 
                designerView.MakeRootDesigner(this.ModelItem);
                this.isMouseDown = false; 
            } 
        }
 
        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            this.lastMouseButtonDownTimeStamp = e.Timestamp;
            bool shouldSetFocus = false; 
            bool shouldUpdateLastActivationPoint = false;
            if (this.ModelItem == null) 
            { 
                return;
            } 
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                this.isMouseDown = true;
                this.lastMouseDownPoint = e.GetPosition(this); 
                if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
                { 
                    this.selectionToggledWithCtrlDown = true; 
                }
                else 
                {
                    this.CaptureMouse();
                }
                shouldSetFocus = Keyboard.FocusedElement != this; 
                e.Handled = true;
                shouldUpdateLastActivationPoint = true; 
            } 
            if (e.LeftButton == MouseButtonState.Pressed && e.ClickCount == 2 && this.Designer.lastClickedDesigner == this)
            { 
                this.MakeRootDesigner();
                Mouse.Capture(null);
                e.Handled = true;
            } 
            if (e.RightButton == MouseButtonState.Pressed)
            { 
                this.lastMouseDownPoint = e.GetPosition(this); 
                shouldSetFocus = Keyboard.FocusedElement != this;
                e.Handled = true; 
                shouldUpdateLastActivationPoint = true;
            }

            System.Diagnostics.Debug.WriteLine( 
                string.Format(CultureInfo.InvariantCulture, "{0} ) WorkflowViewElement.OnMouseDown ({1}, shouldSetFocus {2}, mouseCaptured {3}, raisedBy {4})",
                DateTime.Now.ToLocalTime(), this.GetType().Name, shouldSetFocus, this.IsMouseCaptured, e.OriginalSource)); 
 
            base.OnMouseDown(e);
 
            if (shouldSetFocus)
            {
                System.Diagnostics.Debug.WriteLine(
                    string.Format(CultureInfo.InvariantCulture, "{0} ) WorkflowViewElement.OnMouseDown.SetFocus ({1})", 
                    DateTime.Now.ToLocalTime(), this.GetType().Name));
                //attempt to set focused and keyboard focused element to new designer 
                Keyboard.Focus(this); 
            }
 
            //Change the selection after setting the focus because of CSDMain#130034.
            if (this.selectionToggledWithCtrlDown)
            {
                Selection.Toggle(this.Context, this.ModelItem); 
            }
            else 
            { 
                Selection.SelectOnly(this.Context, this.ModelItem);
            } 

            this.selectionToggledWithCtrlDown = false;

            if (shouldUpdateLastActivationPoint) 
            {
                this.lastActivationElement = e.OriginalSource as UIElement; 
            } 

            if (e.LeftButton == MouseButtonState.Pressed) 
            {
                this.Designer.lastClickedDesigner = this;
            }
        } 

        protected override void OnMouseMove(MouseEventArgs e) 
        { 
            // if model item is removed, uncapture mouse and return
            if (this.ModelItem != null && this.ModelItem != this.ModelItem.Root && this.ModelItem.Parent == null) 
            {
                if (this.IsMouseCaptured)
                {
                    Mouse.Capture(null); 
                }
                return; 
            } 

            if (e.LeftButton == MouseButtonState.Pressed && 
                this.isMouseDown &&
                this.ModelItem != null &&
                e.Timestamp - this.lastMouseButtonDownTimeStamp > 100 &&
                !(this.ModelItem == this.ModelItem.Root)) 
            {
                //get new position 
                Point newPosition = e.GetPosition(this); 
                //calculate distance
                Vector difference = newPosition - this.lastMouseDownPoint; 
                if (Math.Abs(difference.X) > SystemParameters.MinimumHorizontalDragDistance ||
                    Math.Abs(difference.Y) > SystemParameters.MinimumVerticalDragDistance)
                {
                    //if mouse is caputured - release capture, drag&drop infrastructure will take care now for tracking mouse move 
                    if (this.IsMouseCaptured)
                    { 
                        Mouse.Capture(null); 
                        StartDragging();
                    } 

                    this.isMouseDown = false;
                    e.Handled = true;
                } 
            }
            base.OnMouseMove(e); 
        } 

        protected override void OnMouseUp(MouseButtonEventArgs e) 
        {
            System.Diagnostics.Debug.WriteLine(
                CultureInfo.InvariantCulture,
                string.Format(CultureInfo.CurrentUICulture, "{0} ) WorkflowViewElement.OnMouseUp ({1}, mouseCaptured {2})", 
                DateTime.Now.ToLocalTime(), this.GetType().Name, this.IsMouseCaptured));
 
            if (this.isMouseDown) 
            {
                if (this.IsMouseCaptured) 
                {
                    Mouse.Capture(null);
                }
                this.isMouseDown = false; 
                e.Handled = true;
            } 
            base.OnMouseUp(e); 
        }
 
        void OnBreadCrumbTimerElapsed(object sender, ElapsedEventArgs e)
        {
            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
                { 
                    this.breadCrumbTimer.Stop();
                    this.MakeRootDesigner(); 
                })); 
        }
 
        void OnDrag(DragEventArgs e)
        {
            if (!e.Handled)
            { 
                e.Effects = DragDropEffects.None;
                e.Handled = true; 
            } 
        }
 
        // This is to set the cursor to the forbidden icon when dragging to the designer.
        // It doesn't affect the drag-drop behavior of components that have AllowDrop == ture within the designer.
        protected override void OnDragEnter(DragEventArgs e)
        { 
            this.OnDrag(e);
            base.OnDragEnter(e); 
        } 

        // This is to set the cursor to the forbidden icon when dragging within the designer. 
        // It doesn't affect the drag-drop behavior of components that have AllowDrop == ture within the designer.
        protected override void OnDragOver(DragEventArgs e)
        {
            this.OnDrag(e); 
            base.OnDragOver(e);
        } 
 
        protected override void OnPreviewDragEnter(DragEventArgs e)
        { 
            if (this.ShowExpanded == false)
            {
                this.breadCrumbTimer.Start();
            } 
            base.OnPreviewDragEnter(e);
        } 
 
        protected override void OnPreviewDragLeave(DragEventArgs e)
        { 
            this.breadCrumbTimer.Stop();
            base.OnPreviewDragLeave(e);
        }
 
        protected override void OnPreviewMouseUp(MouseButtonEventArgs e)
        { 
            this.breadCrumbTimer.Stop(); 
            base.OnPreviewMouseUp(e);
        } 

        static void OnModelItemChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            WorkflowViewElement viewElement = (WorkflowViewElement)dependencyObject; 
            viewElement.OnModelItemChanged(e.NewValue);
        } 
 
        void BeginDropAnimation(WorkflowViewElement target)
        { 
            DropAnimation opacityAnimation = new DropAnimation();
            target.BeginAnimation(FrameworkElement.OpacityProperty, opacityAnimation);
        }
 
        [SuppressMessage(FxCop.Category.Design, FxCop.Rule.DoNotCatchGeneralExceptionTypes,
            Justification = "Catching all exceptions to avoid VS Crash.")] 
        [SuppressMessage("Reliability", "Reliability108", 
            Justification = "Catching all exceptions to avoid VS crash.")]
 
        void StartDragging()
        {

            try 
            {
                ModelItem movingModelItem = this.ModelItem; 
                ICompositeView sourceContainer = (ICompositeView)DragDropHelper.GetCompositeView(this); 
                if (sourceContainer != null)
                { 
                    using (ModelEditingScope editingScope = movingModelItem.BeginEdit(SR.MoveEditingScopeDescription))
                    {
                        DragDropEffects executedDragDropEffect = DragDropHelper.DoDragMove(this, this.lastMouseDownPoint);
                        //once drag drop is done make sure the CompositeView is notified of the change in data 
                        if (executedDragDropEffect == DragDropEffects.Move)
                        { 
                            sourceContainer.OnItemMoved(movingModelItem); 

                            UIElement movedElement = (UIElement)(movingModelItem.View); 
                            BeginDropAnimation((WorkflowViewElement)movedElement);
                        }
                        editingScope.Complete();
                    } 
                }
            } 
            catch (Exception e) 
            {
                ErrorReporting.ShowErrorMessage(e.Message); 
            }

        }
 
        internal void NotifyContextMenuLoaded(ContextMenu menu)
        { 
            if (null != menu) 
            {
                OnContextMenuLoaded(menu); 
            }
        }

        class WorkflowViewElementAutomationPeer : UIElementAutomationPeer 
        {
            WorkflowViewElement owner; 
 
            public WorkflowViewElementAutomationPeer(WorkflowViewElement owner)
                : base(owner) 
            {
                this.owner = owner;
            }
 
            protected override AutomationControlType GetAutomationControlTypeCore()
            { 
                return AutomationControlType.Custom; 
            }
 

            protected override string GetAutomationIdCore()
            {
                string automationId = this.GetClassNameCore(); 
                string automationIdVariablePartMemberName = owner.GetAutomationIdMemberName();
                if (!string.IsNullOrEmpty(automationIdVariablePartMemberName)) 
                { 
                    ModelItem modelItem = this.owner.ModelItem;
                    string variablePartOfAutomationId = string.Empty; 
                    if (modelItem != null)
                    {
                        ModelProperty property = modelItem.Properties[automationIdVariablePartMemberName];
                        Fx.Assert(property != null, "property to use for Automation ID variable part missing ? are you using the right property Name?"); 
                        if (property.Value != null)
                        { 
                            variablePartOfAutomationId = property.Value.GetCurrentValue().ToString(); 
                        }
                    } 
                    automationId = variablePartOfAutomationId + "(" + this.GetClassNameCore() + ")";
                }
                return automationId;
            } 

            protected override string GetNameCore() 
            { 
                Type itemType = null;
                if (this.owner.ModelItem != null) 
                {
                    itemType = this.owner.ModelItem.ItemType;
                }
                else 
                {
                    itemType = this.owner.GetType(); 
                } 

                if (itemType.IsGenericType) 
                {
                    //append the argument types for generic types
                    //we expect the single level of generic is sufficient for the screen reader, so we're no going into
                    //nesting of generic types 
                    Type[] argumentTypes = itemType.GetGenericArguments();
                    StringBuilder name = new StringBuilder(itemType.Name); 
                    name.Append('['); 
                    foreach (Type argument in argumentTypes)
                    { 
                        name.Append(argument.Name);
                        name.Append(',');
                    }
                    name.Replace(',', ']', name.Length - 1, 1); 
                    return name.ToString();
                } 
                else 
                {
                    return itemType.Name; 
                }
            }

            protected override string GetHelpTextCore() 
            {
                return this.owner.GetAutomationHelpText(); 
            } 

            protected override string GetClassNameCore() 
            {
                return this.owner.GetType().Name;
            }
        } 
    }
 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

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