WorkflowItemPresenter.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 / NetFx40 / Tools / System.Activities.Presentation / System / Activities / Presentation / WorkflowItemPresenter.cs / 1305376 / WorkflowItemPresenter.cs

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

namespace System.Activities.Presentation 
{
    using System.Activities.Presentation.Model; 
    using System.Activities.Presentation.Services; 
    using System.Collections;
    using System.Collections.Generic; 
    using System.Linq;
    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.Threading;
    using System.Activities.Presentation.View; 


    // This class provides a visual edit box to edit ModelItems. Textbox offers to edit strings, ints as a TextBlock and a cursor visually,
    // The workflowitempresenter edits modelitems by picking their view using the view service. It presents s the visual for the modelitem 
    // pointe by Item property if it is set, it shows the hint text if the property is not set. It allows the associated item to be deleted
    // visually , and removes the reference to Item when deleted. It also allows droping ModelItems, to set the Item property to the dropped 
    // item. 
    public sealed class WorkflowItemPresenter : ContentControl, ICompositeView
    { 

        public static readonly DependencyProperty HintTextProperty =
            DependencyProperty.Register("HintText", typeof(string), typeof(WorkflowItemPresenter), new UIPropertyMetadata(String.Empty));
 
        public static readonly DependencyProperty ItemProperty =
            DependencyProperty.Register("Item", typeof(ModelItem), typeof(WorkflowItemPresenter), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(WorkflowItemPresenter.OnItemChanged))); 
 
        public static readonly DependencyProperty AllowedItemTypeProperty =
            DependencyProperty.Register("AllowedItemType", typeof(Type), typeof(WorkflowItemPresenter), new UIPropertyMetadata(typeof(object))); 

        public static readonly DependencyProperty IsDefaultContainerProperty =
            DependencyProperty.Register("IsDefaultContainer", typeof(bool), typeof(WorkflowItemPresenter), new UIPropertyMetadata(false));
 
        public static readonly DependencyProperty DroppingTypeResolvingOptionsProperty =
            DependencyProperty.Register("DroppingTypeResolvingOptions", typeof(TypeResolvingOptions), typeof(WorkflowItemPresenter)); 
 
        Grid contentGrid;
        TextBlock text; 
        EditingContext context = null;
        bool shouldSetFocus = false;
        bool isItemPastedOrDropped = false;
 
        public WorkflowItemPresenter()
        { 
            contentGrid = new Grid(); 
            text = new TextBlock();
            text.SetBinding(TextBlock.TextProperty, "HintText"); 
            text.DataContext = this;
            text.HorizontalAlignment = HorizontalAlignment.Center;
            text.VerticalAlignment = VerticalAlignment.Center;
            text.Foreground = new SolidColorBrush(SystemColors.GrayTextColor); 
            text.FontStyle = FontStyles.Italic;
            contentGrid.Background = Brushes.Transparent; 
            contentGrid.Children.Add(text); 
        }
 
        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);
            this.AllowDrop = true; 
            this.Content = contentGrid;
            ICompositeViewEvents containerEvents = null; 
            bool isDefault = false; 

            this.Loaded += (s, eventArgs) => 
            {
                isDefault = this.IsDefaultContainer;
                DependencyObject parent = VisualTreeHelper.GetParent(this);
                while (null != parent && !typeof(ICompositeViewEvents).IsAssignableFrom(parent.GetType())) 
                {
                    parent = VisualTreeHelper.GetParent(parent); 
                } 
                containerEvents = parent as ICompositeViewEvents;
                if (null != containerEvents) 
                {
                    if (isDefault)
                    {
                        containerEvents.RegisterDefaultCompositeView(this); 
                    }
                    else 
                    { 
                        containerEvents.RegisterCompositeView(this);
                    } 
                }
                this.shouldSetFocus = true;
            };
 
            this.Unloaded += (s, eventArgs) =>
            { 
                if (null != containerEvents) 
                {
                    if (isDefault) 
                    {
                        containerEvents.UnregisterDefaultCompositeView(this);
                    }
                    else 
                    {
                        containerEvents.UnregisterCompositeView(this); 
                    } 
                }
                this.shouldSetFocus = false; 
            };
        }

        public string HintText 
        {
            get { return (string)GetValue(HintTextProperty); } 
            set { SetValue(HintTextProperty, value); } 
        }
 
        [Fx.Tag.KnownXamlExternal]
        public ModelItem Item
        {
            get { return (ModelItem)GetValue(ItemProperty); } 
            set { SetValue(ItemProperty, value); }
        } 
 
        public Type AllowedItemType
        { 
            get { return (Type)GetValue(AllowedItemTypeProperty); }
            set { SetValue(AllowedItemTypeProperty, value); }
        }
 
        [Fx.Tag.KnownXamlExternal]
        public TypeResolvingOptions DroppingTypeResolvingOptions 
        { 
            get { return (TypeResolvingOptions)GetValue(DroppingTypeResolvingOptionsProperty); }
            set { SetValue(DroppingTypeResolvingOptionsProperty, value); } 
        }

        EditingContext Context
        { 
            get
            { 
                if (context == null) 
                {
                    IModelTreeItem modelTreeItem = this.Item as IModelTreeItem; 
                    if (modelTreeItem != null)
                    {
                        this.context = modelTreeItem.ModelTreeManager.Context;
                    } 
                    else // There is no ModelItem yet, try to walk up the tree to find a WorkflowViewElement.
                    { 
                        WorkflowViewElement parentViewElement = GetParentWorkflowViewElement(); 
                        if (parentViewElement != null)
                        { 
                            this.context = parentViewElement.Context;
                        }
                    }
                } 
                return context;
            } 
        } 

 
        public bool IsDefaultContainer
        {
            get { return (bool)GetValue(IsDefaultContainerProperty); }
            set { SetValue(IsDefaultContainerProperty, value); } 
        }
 
        protected override void OnRender(DrawingContext drawingContext) 
        {
            CutCopyPasteHelper.RegisterWithParentViewElement(this); 
            base.OnRender(drawingContext);
        }

        private WorkflowViewElement GetParentWorkflowViewElement() 
        {
            // Walk the logic tree first. 
            FrameworkElement parent = (FrameworkElement)this.Parent; 
            while (parent != null && !(parent is WorkflowViewElement))
            { 
                parent = parent.Parent as FrameworkElement;
            }
            WorkflowViewElement result = parent as WorkflowViewElement;
            // If not found, walk the visual tree. 
            if (null == result)
            { 
                parent = VisualTreeHelper.GetParent(this) as FrameworkElement; 
                while (parent != null && !(parent is WorkflowViewElement))
                { 
                    parent = VisualTreeHelper.GetParent(parent) as FrameworkElement;
                }
                result = parent as WorkflowViewElement;
            } 
            return result;
        } 
 

        static void OnItemChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
        {
            WorkflowItemPresenter control = (WorkflowItemPresenter)dependencyObject;
            control.OnItemChanged(e);
        } 

        void OnItemChanged(DependencyPropertyChangedEventArgs e) 
        { 
            object newItem = e.NewValue;
            PopulateContent(); 
            if (newItem != null)
            {
                //We want to set the selection only if the item is dropped or pasted.
                //We cannot set the selection in UpdateItem, since while pasting that would still be in EditingScope and this.Item will be null. 
                if (this.isItemPastedOrDropped)
                { 
                    Fx.Assert(this.Item != null, "Item cannot be null"); 
                    // If we are currently moving from somewhere else to a WorkflowItemPresenter, the currently
                    // focusing view element will be removed, we need to set the keyboard focus explicitly to 
                    // avoid WPF FocusManager to focus on an element, leading to flashing effect.
                    Keyboard.Focus((UIElement)this.Item.View);
                    this.isItemPastedOrDropped = false;
                } 
                if (this.shouldSetFocus)
                { 
                    this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() => 
                    {
                        // check for Item == null, we found an interesting bug, where the user 
                        // could drop something in here, and undo the change before the code below
                        // could execute
                        if (this.Item != null)
                        { 
                            UIElement view = (UIElement)(this.Item.View);
                            if (view != null) 
                            { 
                                Keyboard.Focus(view);
                                Selection.SelectOnly(this.Context, this.Item); 
                            }
                        }
                        //this.shouldSetFocus = false;
                    })); 
                }
            } 
            else 
            {
                // remove the selection if the previous value was selected. 
                if (this.Context != null)
                {
                    if (this.Context.Items.GetValue().SelectedObjects.Contains(e.OldValue))
                    { 
                        this.Context.Items.SetValue(new Selection(new ModelItem[] { }));
                    } 
                } 
            }
        } 


        void PopulateContent()
        { 
            if (this.Item != null)
            { 
                VirtualizedContainerService containerService = this.Context.Services.GetService(); 
                UIElement itemView = containerService.GetContainer(this.Item, this);
                this.contentGrid.Children.Clear(); 
                this.contentGrid.Children.Add(itemView);
            }
            else
            { 
                contentGrid.Children.Clear();
                contentGrid.Children.Add(text); 
            } 
        }
 
        bool UpdateItem(object newItem)
        {
            bool updateSucceeded = false;
            ModelItem newModelItem = newItem as ModelItem; 
            if (this.Item == null)
            { 
                if (newModelItem == null && newItem != null) 
                {
                    // try to wrap the droppedObject in  a ModelItem. 
                    ModelServiceImpl modelService = (ModelServiceImpl)this.Context.Services.GetService();
                    newModelItem = modelService.WrapAsModelItem(newItem);
                }
                if (this.CanUpdateItem(newModelItem)) 
                {
                    // In order to allow for model updates that happens during the model item is drop, this is all done in an atomic unit. 
                    using (ModelEditingScope editingScope = this.Context.Services.GetService().Root.BeginEdit(SR.PropertyChangeEditingScopeDescription)) 
                    {
                        this.Item = newModelItem; 
                        editingScope.Complete();
                    }
                    updateSucceeded = true;
                    this.isItemPastedOrDropped = true; 
                }
            } 
            return updateSucceeded; 

        } 

        bool CanUpdateItem(ModelItem newModelItem)
        {
            return null != newModelItem && this.AllowedItemType.IsAssignableFrom(newModelItem.ItemType) && !this.IsInParentChain(newModelItem); 
        }
 
        protected override void OnDrop(DragEventArgs e) 
        {
            object droppedObject = DragDropHelper.GetDroppedObject(this, e, Context); 
            DragDropHelper.SetDragDropCompletedEffects(e, DragDropEffects.None);
            if (UpdateItem(droppedObject))
            {
                e.Handled = true; 
                DragDropHelper.SetDragDropCompletedEffects(e, DragDropEffects.Move);
            } 
            base.OnDrop(e); 
        }
 
        void OnDrag(DragEventArgs e)
        {
            if (!e.Handled)
            { 
                if (null != this.Item || !DragDropHelper.AllowDrop(e.Data, this.Context, this.AllowedItemType))
                { 
                    e.Effects = DragDropEffects.None; 
                }
                e.Handled = true; 
            }
        }

        protected override void OnDragEnter(DragEventArgs e) 
        {
            this.OnDrag(e); 
            base.OnDragEnter(e); 
        }
 
        protected override void OnDragOver(DragEventArgs e)
        {
            this.OnDrag(e);
            base.OnDragOver(e); 
        }
 
        protected override void OnMouseDown(MouseButtonEventArgs e) 
        {
            // Schedule the Keyboard.Focus command to let it execute later than WorkflowViewElement.OnMouseDown, 
            // where WorkflowViewElement will move the keyboard focus on itself
            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
            {
                Keyboard.Focus((FrameworkElement)this); 
            }));
            base.OnMouseDown(e); 
        } 

        private bool IsInParentChain(ModelItem droppedModelItem) 
        {
            bool isInParentChain = false;
            // start with immediate workflowviewElement outside this.
            WorkflowViewElement parentViewElement = GetParentWorkflowViewElement(); 
            if (parentViewElement != null)
            { 
                ModelItem parentModelItem = parentViewElement.ModelItem; 
                while (parentModelItem != null)
                { 
                    if (parentModelItem == droppedModelItem)
                    {
                        isInParentChain = true;
                        break; 
                    }
                    parentModelItem = parentModelItem.Parent; 
                } 
            }
            return isInParentChain; 
        }

        void DeleteItem()
        { 
            this.Item = null;
            this.PopulateContent(); 
        } 

        void ICompositeView.OnItemMoved(ModelItem modelItem) 
        {
            if (this.Item == modelItem)
            {
                this.Item = null; 
            }
        } 
 
        protected override AutomationPeer OnCreateAutomationPeer()
        { 
            return new WorkflowItemPresenterAutomationPeer(this);
        }

 
        object ICompositeView.OnItemsCut(List itemsToCut)
        { 
            Fx.Assert(itemsToCut.Count == 1, "Only one item can be cut"); 
            Fx.Assert(itemsToCut[0].Equals(this.Item), "Only one item can be cut.");
            this.DeleteItem(); 
            return null;
        }

        object ICompositeView.OnItemsCopied(List itemsToCopy) 
        {
            return null; 
        } 

        void ICompositeView.OnItemsPasted(List itemsToPaste, List metaData, Point pastePoint, WorkflowViewElement pastePointReference) 
        {
            if (itemsToPaste.Count == 1)
            {
                UpdateItem(itemsToPaste[0]); 
            }
        } 
 
        void ICompositeView.OnItemsDelete(List itemsToDelete)
        { 
            if (null != itemsToDelete && itemsToDelete.Contains(this.Item))
            {
                this.DeleteItem();
            } 
        }
 
 
        bool ICompositeView.CanPasteItems(List itemsToPaste)
        { 
            return null != itemsToPaste &&
                1 == itemsToPaste.Count &&
                null != itemsToPaste[0] &&
                null == this.Item && 
                ((itemsToPaste[0] is ModelItem && this.CanUpdateItem((ModelItem)itemsToPaste[0])) ||
                (itemsToPaste[0] is Type && this.AllowedItemType.IsAssignableFrom((Type)itemsToPaste[0])) || 
                this.AllowedItemType.IsAssignableFrom(itemsToPaste[0].GetType())); 
        }
 

        class WorkflowItemPresenterAutomationPeer : UIElementAutomationPeer
        {
            WorkflowItemPresenter owner; 

            public WorkflowItemPresenterAutomationPeer(WorkflowItemPresenter owner) 
                : base(owner) 
            {
                this.owner = owner; 
            }

            protected override AutomationControlType GetAutomationControlTypeCore()
            { 
                return AutomationControlType.Custom;
            } 
 
            protected override string GetAutomationIdCore()
            { 
                string baseAutomationID = base.GetAutomationIdCore();
                if (!string.IsNullOrEmpty(baseAutomationID))
                {
                    return baseAutomationID; 
                }
                return this.owner.GetType().Name; 
            } 

            protected override string GetNameCore() 
            {
                // Return an empty string if an activity is dropped on the presenter
                if (owner.Item != null)
                { 
                    return string.Empty;
                } 
                string name = base.GetNameCore(); 
                if (string.IsNullOrEmpty(name))
                { 
                    name = this.owner.HintText;
                }
                return name;
            } 

            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