DesignerView.xaml.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 / View / DesignerView.xaml.cs / 1407647 / DesignerView.xaml.cs

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

namespace System.Activities.Presentation.View 
{
    using System.Activities.Presentation.View; 
    using System.Activities.Presentation.Model; 
    using System.Activities.Presentation.Services;
    using System.Activities.Presentation.Xaml; 
    using System.Activities.Presentation.Hosting;
    using System.Collections;
    using System.Collections.ObjectModel;
    using System.ComponentModel; 
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization; 
    using System.IO; 
    using System.IO.Packaging;
    using System.Printing; 
    using System.Reflection;
    using System.Runtime;
    using System.Windows;
    using System.Windows.Controls; 
    using System.Windows.Controls.Primitives;
    using System.Windows.Data; 
    using System.Windows.Documents; 
    using System.Windows.Input;
    using System.Windows.Interop; 
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Threading;
    using System.Windows.Xps; 
    using System.Windows.Xps.Packaging;
    using System.Linq; 
    using System.Windows.Shapes; 
    using System.Collections.Generic;
    using System.Activities.Presentation.Validation; 
    using System.Diagnostics;
    using System.Activities.Presentation.Internal.PropertyEditing;
    using System.ServiceModel.Activities;
 
    // 
    // Interaction logic for DesignerView.xaml 
    //  
    [Fx.Tag.XamlVisible(false)]
    public partial class DesignerView : UserControl 
    {
        public static readonly DependencyProperty RootDesignerProperty =
            DependencyProperty.Register("RootDesigner", typeof(UIElement), typeof(DesignerView), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(DesignerView.OnRootDesignerChanged)));
 
        public static readonly DependencyProperty IsReadOnlyProperty =
            DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(DesignerView), new UIPropertyMetadata(OnIsReadOnlyChanged)); 
 
        static readonly DependencyPropertyKey ActivitySchemaPropertyKey =
            DependencyProperty.RegisterReadOnly("ActivitySchema", typeof(ModelItem), typeof(DesignerView), new UIPropertyMetadata(OnActivitySchemaChanged)); 

        public static readonly DependencyProperty ActivitySchemaProperty = ActivitySchemaPropertyKey.DependencyProperty;

        static readonly DependencyPropertyKey FocusedViewElementPropertyKey = 
            DependencyProperty.RegisterReadOnly("FocusedViewElement", typeof(WorkflowViewElement), typeof(DesignerView), new UIPropertyMetadata(null));
 
        public static readonly DependencyProperty FocusedViewElementProperty = FocusedViewElementPropertyKey.DependencyProperty; 

        internal static DependencyProperty ShouldExpandAllProperty = DependencyProperty.Register("ShouldExpandAll", typeof(bool), typeof(DesignerView), new PropertyMetadata(false, new PropertyChangedCallback(OnExpandAllCollapseAllChanged))); 
        internal static DependencyProperty ShouldCollapseAllProperty = DependencyProperty.Register("ShouldCollapseAll", typeof(bool), typeof(DesignerView), new PropertyMetadata(false, new PropertyChangedCallback(OnExpandAllCollapseAllChanged)));

        const double scrollDeltaDivider = 100.0;
 
        GridLength bottomPaneHeight;
        EditingContext context; 
        DragDropHelper.ViewElementDragShadow viewElementDragShadow; 
        ZoomToTicksConverter zoomToTicksConverter;
        ShellBarItemVisibility shellBarItemVisibility = ShellBarItemVisibility.Variables | ShellBarItemVisibility.Arguments | ShellBarItemVisibility.Imports; 
        Dictionary selectionMap = new Dictionary();
        Point dpiScale = new Point(1.0, 1.0);
        private bool isInErrorState = false;
 
        const string breadCrumbRootKey = "BreadCrumbRoot";
        const string selectionKey = "Selection"; 
 

        internal WorkflowViewElement lastClickedDesigner; 

        private DesignerView()
        {
        } 

        internal DesignerView(EditingContext context) 
        { 
            this.context = context;
            InitializeComponent(); 
            this.InitializeMenuActions();
            foreach (UIElement element in this.designerExtensionSurface.Children)
            {
                element.IsEnabled = false; 
            }
 
            this.buttonArguments1.Visibility = Visibility.Hidden; 
            this.buttonArguments1.IsChecked = false;
            Grid.SetColumn(importsStatusBarItem, 3); 

            this.zoomToTicksConverter = new ZoomToTicksConverter(this, this.zoomSlider, this.zoomPicker);
            this.zoomSlider.ValueChanged += new RoutedPropertyChangedEventHandler(OnZoomSliderValueChanged);
            HideBottomPane(); 

            this.variables1.VariableCollectionChanged += this.OnVariablesCollectionChanged; 
            this.arguments1.ArgumentCollectionChanged += this.OnArgumentsCollectionChanged; 
            Dispatcher.UnhandledException += new DispatcherUnhandledExceptionEventHandler(OnDispatcherUnhandledException);
            this.ShouldIgnoreDataGridAutoCommit = false; 
        }

        void OnReadOnlyStateChanged(ReadOnlyState state)
        { 
            this.IsReadOnly = state.IsReadOnly;
        } 
 
        void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        { 
            if (!e.Handled)
            {
                if (!isInErrorState)
                { 
                    isInErrorState = true;
 
                    //try to prun the visual tree and collapse all the workflow view elements that are too deep 
                    //this is due to the limitation of WPF has a visual tree depth limit.
                    if (e.Exception is InvalidOperationException) 
                    {
                        ICollection deepElements = VisualTreeUtils.PrunVisualTree(this.RootDesigner);
                        foreach (WorkflowViewElement viewElement in deepElements)
                        { 
                            viewElement.ForceCollapse();
                        } 
                    } 
                    Exception ex = e.Exception.InnerException ?? e.Exception;
                    ErrorReporting.ShowErrorMessage(ex); 
                    isInErrorState = false;
                }
                e.Handled = true;
            } 
        }
 
        public bool IsMultipleSelectionMode 
        {
            get; 
            private set;
        }

        void OnDesignerViewLoaded(object sender, RoutedEventArgs e) 
        {
            ViewStateService viewStateService = this.Context.Services.GetService(); 
            ModelTreeManager modelTreeManager = this.context.Services.GetService(); 
            //Initialize ShouldExpandAll if it exists in ViewState.
            object expandAllState = viewStateService.RetrieveViewState(modelTreeManager.Root, DesignerView.ShouldExpandAllProperty.Name); 
            if (expandAllState != null)
            {
                this.ShouldExpandAll = (bool)expandAllState;
            } 
            if (!this.ShouldExpandAll)
            { 
                object collapseAllState = viewStateService.RetrieveViewState(modelTreeManager.Root, DesignerView.ShouldCollapseAllProperty.Name); 
                if (collapseAllState != null)
                { 
                    this.ShouldCollapseAll = (bool)collapseAllState;
                }
            }
 
        }
 
        static void OnExpandAllCollapseAllChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) 
        {
            ((DesignerView)o).OnExpandAllCollapseAllChanged(e); 
        }

        void OnExpandAllCollapseAllChanged(DependencyPropertyChangedEventArgs e)
        { 
            ViewStateService viewStateService = this.Context.Services.GetService();
            ModelTreeManager modelTreeManager = this.context.Services.GetService(); 
            { 
                viewStateService.StoreViewState(modelTreeManager.Root, e.Property.Name, e.NewValue);
            } 
        }


        protected override void OnInitialized(EventArgs e) 
        {
            this.AddHandler(UIElement.GotKeyboardFocusEvent, new KeyboardFocusChangedEventHandler(this.OnWorkflowElementGotKeyboardFocus), true); 
            this.AddHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.OnDesignerSurfaceMouseLeftButtonDown), true); 
            base.OnInitialized(e);
            this.Foreground = new SolidColorBrush(SystemColors.ControlTextColor); 
            this.Loaded += this.OnDesignerViewLoaded;
            this.IsKeyboardFocusWithinChanged += this.OnDesignerKeyboardFocusWithinChanged;

            this.MenuItemStyle = (Style)this.FindResource("menuItemStyle"); 
            Fx.Assert(this.MenuItemStyle != null, "menuItemStyle resource not found");
            this.MenuSeparatorStyle = (Style)this.FindResource("separatorStyle"); 
            Fx.Assert(this.MenuSeparatorStyle != null, "separatorStyle resource not found"); 

            ReadOnlyState state = this.Context.Items.GetValue(); 
            this.IsReadOnly = state.IsReadOnly;
            this.Context.Items.Subscribe(OnReadOnlyStateChanged);
        }
 
        public ModelItem ActivitySchema
        { 
            get { return (ModelItem)GetValue(ActivitySchemaProperty); } 
            private set { SetValue(ActivitySchemaPropertyKey, value); }
        } 

        public EditingContext Context
        {
            get { return this.context; } 
        }
 
        public UIElement RootDesigner 
        {
            get { return (UIElement)GetValue(RootDesignerProperty); } 
            set { SetValue(RootDesignerProperty, value); }
        }

        public bool ShouldExpandAll 
        {
            get { return (bool)GetValue(ShouldExpandAllProperty); } 
            set { SetValue(ShouldExpandAllProperty, value); } 
        }
 
        public bool ShouldCollapseAll
        {
            get { return (bool)GetValue(ShouldCollapseAllProperty); }
            set { SetValue(ShouldCollapseAllProperty, value); } 
        }
 
        public bool IsReadOnly 
        {
            get { return (bool)GetValue(IsReadOnlyProperty); } 
            set { SetValue(IsReadOnlyProperty, value); }
        }

        public WorkflowViewElement FocusedViewElement 
        {
            get { return (WorkflowViewElement)GetValue(FocusedViewElementProperty); } 
            private set { SetValue(FocusedViewElementPropertyKey, value); } 
        }
 
        internal double ZoomFactor
        {
            get
            { 
                return this.zoomToTicksConverter.ZoomFactor;
            } 
        } 

        internal ScrollViewer ScrollViewer 
        {
            get
            {
                return this.scrollViewer; 
            }
        } 
 

        internal UIElement ScrollableContent 
        {
            get
            {
                return this.scrollableContent; 
            }
        } 
 
        internal bool ShouldIgnoreDataGridAutoCommit
        { 
            get;
            set;
        }
 
        public ShellBarItemVisibility WorkflowShellBarItemVisibility
        { 
            get { return this.shellBarItemVisibility; } 
            set { this.ApplyShellBarItemVisibility(value); }
        } 

        public void MakeRootDesigner(ModelItem modelItem)
        {
            bool checkIfCanBeMadeRoot = true; 
            if (modelItem == modelItem.Root)
            { 
                checkIfCanBeMadeRoot = false; 
            }
            MakeRootDesigner(modelItem, /* setAsSelection = */ true, checkIfCanBeMadeRoot); 
        }

        internal void MakeRootDesigner(ModelItem modelItem, bool setAsSelection)
        { 
            MakeRootDesigner(modelItem, setAsSelection, true);
        } 
 
        internal void ForceMakeRootDesigner(ModelItem modelItem)
        { 
            MakeRootDesigner(modelItem, /* setAsSelection = */ true, false);
        }

        static bool IsSwitchCase(ModelItem modelItem) 
        {
            if(IsModelItemKeyValuePair(modelItem.ItemType)) 
            { 
                if (modelItem.Parent != null && //modelItem.Parent - ItemsCollection
                    modelItem.Parent.Parent != null && //modelItem.Parent.Parent - Cases 
                    modelItem.Parent.Parent.Parent != null && //modelItem.Parent.Parent.Parent - Switch
                    modelItem.Parent.Parent.Parent.ItemType.IsGenericType &&
                    modelItem.Parent.Parent.Parent.ItemType.GetGenericTypeDefinition() == typeof(System.Activities.Statements.Switch<>))
                { 
                    return true;
                } 
            } 
            return false;
        } 

        static bool IsModelItemKeyValuePair(Type type)
        {
            return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ModelItemKeyValuePair<,>); 
        }
 
        void SelectAll() 
        {
            WorkflowViewElement root = this.RootDesigner as WorkflowViewElement; 
            ModelItem rootModelItem = null;
            if (root != null)
            {
                rootModelItem = root.ModelItem; 
            }
            if (rootModelItem != null) 
            { 
                ModelTreeManager modelTreeManager = this.Context.Services.GetService();
                IEnumerable items = modelTreeManager.Find(rootModelItem, delegate(Type type) 
                {
                    WorkflowViewService viewService = this.Context.Services.GetService() as WorkflowViewService;
                    return (typeof(WorkflowViewElement).IsAssignableFrom(viewService.GetDesignerType(type)));
                }, true); 
                IEnumerable itemsToSelect = items
                    // ModelItemKeyValuePair is associated with CaseDesigner. 
                    // So ModelItemKeyValuePair will be returned even if they are not really Cases. 
                    // Those ModelItemKeyValuePairs need to be excluded.
                    .Where(item => !IsModelItemKeyValuePair(item.ItemType) || IsSwitchCase(item)) 
                    .Except(new ModelItem[] {rootModelItem});
                Selection selection = new Selection(itemsToSelect);
                this.Context.Items.SetValue(selection);
            } 
        }
 
        internal void BeginDragShadowTracking(DragDropHelper.ViewElementDragShadow dragShadow) 
        {
            AdornerLayer layer = AdornerLayer.GetAdornerLayer(this.scrollableContent); 
            if (null != layer)
            {
                layer.Add(dragShadow);
                this.viewElementDragShadow = dragShadow; 
                //get parent window handle
                HwndSource relativeSource = (HwndSource)PresentationSource.FromVisual(this.scrollViewer); 
                this.viewElementDragShadow.LayerHWND = relativeSource.Handle; 
                //get relative position of scrollable designer area to its containing window
                GeneralTransform transform = this.scrollViewer.TransformToAncestor(relativeSource.RootVisual); 
                Point offset = transform.Transform(new Point());
                //get current dpi settings
                var matrix = relativeSource.CompositionTarget.TransformFromDevice;
                //store scaling information for calculation of screen position 
                this.dpiScale = new Point(matrix.M11, matrix.M22);
                //update view element's shadow with that offset 
                this.viewElementDragShadow.UpdateOffset(offset.X, offset.Y); 

                //register for window messages notification 
                this.Context.Services.GetService().RegisterWindowMessageHandler(new WindowMessage(OnMessage));
            }
        }
 
        internal void EndDragShadowTracking(DragDropHelper.ViewElementDragShadow dragShadow)
        { 
            AdornerLayer layer = AdornerLayer.GetAdornerLayer(this.scrollableContent); 
            if (null != layer)
            { 
                //unregister from window message notification
                this.Context.Services.GetService().UnregisterWindowMessageHandler(new WindowMessage(OnMessage));
                layer.Remove(dragShadow);
                this.viewElementDragShadow = null; 
            }
        } 
 
        static void UpdateAncestorFlag(ModelItem oldRoot, ModelItem newRoot)
        { 
            // Walk up the tree and update the flags from the new root. If we hit the old root in the process, we are done.
            // Otherwise, continue to update the flags from the old root until we hit the new root.
            if (oldRoot == newRoot)
            { 
                return;
            } 
            bool hitOldRoot = false; 
            if (newRoot != null)
            { 
                WorkflowViewElement viewElement = newRoot.View as WorkflowViewElement;
                if (viewElement != null)
                {
                    viewElement.IsAncestorOfRootDesigner = false; 
                }
                ModelItem parent = newRoot.Parent; 
                while (parent != null) 
                {
                    WorkflowViewElement view = parent.View as WorkflowViewElement; 
                    if (view != null)
                    {
                        view.IsAncestorOfRootDesigner = true;
                    } 
                    if (parent == oldRoot)
                    { 
                        hitOldRoot = true; 
                    }
                    parent = parent.Parent; 
                }
            }
            if (oldRoot != null && !hitOldRoot)
            { 
                ModelItem parent = oldRoot.Parent;
                while (parent != null && parent != newRoot) 
                { 
                    WorkflowViewElement view = parent.View as WorkflowViewElement;
                    if (view != null) 
                    {
                        view.IsAncestorOfRootDesigner = false;
                    }
                    parent = parent.Parent; 
                }
            } 
        } 

        internal void MakeRootDesigner(ModelItem modelItem, bool setAsSelection, bool checkIfCanBeMadeRoot) 
        {
            ModelItem currentRootModelItem = (this.RootDesigner != null) ? ((WorkflowViewElement)this.RootDesigner).ModelItem : null;
            if (modelItem == currentRootModelItem)
            { 
                return;
            } 
            if (typeof(ActivityBuilder).IsAssignableFrom(modelItem.ItemType)) 
            {
                this.ActivitySchema = modelItem; 
            }

            WorkflowViewService viewService = this.Context.Services.GetService() as WorkflowViewService;
 
            //try get designer for given model item
            Type designerType = viewService.GetDesignerType(modelItem.ItemType); 
            //if one doesn't exist - check its parent tree, perhaps there will be one 
            while (null == designerType && null != modelItem.Parent)
            { 
                modelItem = modelItem.Parent;
                designerType = viewService.GetDesignerType(modelItem.ItemType);
            }
 
            if (viewService.ShouldAppearOnBreadCrumb(modelItem, checkIfCanBeMadeRoot))
            { 
                UpdateAncestorFlag(currentRootModelItem, modelItem); 
                Dictionary newSelectionMap = new Dictionary();
                ModelItem newRootModelItem = modelItem; 
                ObservableCollection breadCrumbCollection = new ObservableCollection();
                object breadCrumbObjectConnector = null;
                bool isFirstAdded = false;
                while (modelItem != null) 
                {
                    bool shouldCheckIfCanBeMadeRoot = true; 
                    if (isFirstAdded) 
                    {
                        shouldCheckIfCanBeMadeRoot = checkIfCanBeMadeRoot; 
                    }
                    if (viewService.ShouldAppearOnBreadCrumb(modelItem, shouldCheckIfCanBeMadeRoot))
                    {
                        if (isFirstAdded) 
                        {
                            breadCrumbObjectConnector = new BreadCrumbObjectSeparator(); 
                            breadCrumbCollection.Insert(0, breadCrumbObjectConnector); 
                        }
                        breadCrumbCollection.Insert(0, modelItem); 
                        isFirstAdded = true;
                        if (selectionMap.ContainsKey(modelItem))
                        {
                            newSelectionMap.Add(modelItem, selectionMap[modelItem]); 
                        }
                    } 
                    modelItem = modelItem.Parent; 
                }
 
                //Remember the selection for the current root.
                WorkflowViewElement focusedElement = Keyboard.FocusedElement as WorkflowViewElement;
                //This condition will be true when we are breadcrumbing into a child element.
                if (focusedElement != null && object.Equals(focusedElement.ModelItem, newRootModelItem)) 
                {
                    if (currentRootModelItem != null) 
                    { 
                        newSelectionMap[currentRootModelItem] = newRootModelItem;
                    } 
                }
                this.selectionMap = newSelectionMap;
                SetAsRootDesignerView(newRootModelItem, setAsSelection);
                breadCrumbListBox.ItemsSource = breadCrumbCollection; 
                // Move to the top left so that the display name is visible.
                this.ScrollViewer.ScrollToTop(); 
                this.ScrollViewer.ScrollToLeftEnd(); 
            }
        } 



        void OnMessage(int msgId, IntPtr wParam, IntPtr lParam) 
        {
            //WM_NCHITTEST message is the only message beeing routed when dragging an activity over elements which do not support 
            //drag & drop; in order to provide smooth dragging expirience i have to get coordinates from this message and update 
            //drag shadow with them
            //consider this message only when we are in drag mode 
            if (null != this.viewElementDragShadow && Win32Interop.WM_NCHITTEST == msgId)
            {
                //get current mouse screen coordinates out of LPARAM
                uint pos = (uint)lParam; 
                Win32Interop.POINT screenPoint = new Win32Interop.POINT((int)(pos & 0xffff), (int)(pos >> 16));
                //convert screen coordinates to window's coordinates 
                if (Win32Interop.ScreenToClient(this.viewElementDragShadow.LayerHWND, screenPoint) != 0) 
                {
                    //update shadow's position; scale raw coordinates with current display's DPI settings (WPF requires it) 
                    this.viewElementDragShadow.UpdatePosition(screenPoint.x * this.dpiScale.X, screenPoint.y * this.dpiScale.Y);
                }
            }
        } 

        void OnWorkflowElementGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) 
        { 
            FrameworkElement source = e.NewFocus as FrameworkElement;
            //walk up visual tree, but not above DesignerView - there won't be any design shapes anyway 
            while (null != source && this != source)
            {
                //select first visual, which is of type WorkflowViewElement
                if (typeof(WorkflowViewElement).IsAssignableFrom(source.GetType())) 
                {
                    break; 
                } 
                source = VisualTreeHelper.GetParent(source) as FrameworkElement;
            } 
            //try to cast source element as WorkflowViewElement
            if (this.FocusedViewElement != source)
            {
                this.FocusedViewElement = source as WorkflowViewElement; 

                System.Diagnostics.Debug.WriteLine( 
                    string.Format(CultureInfo.InvariantCulture, "{0} ) DesignerView.OnWorkflowElementGotKeyboardFocus(FocusedViewElement {1}, raisedBy {2})", 
                    DateTime.Now.ToLocalTime(), (null == this.FocusedViewElement ? "" : this.FocusedViewElement.GetType().Name), e.OriginalSource));
            } 
        }

        void OnDesignerKeyboardFocusWithinChanged(object sender, DependencyPropertyChangedEventArgs e)
        { 
            //if current designer lost keyboard focus - commit pending edits
            if (!this.IsKeyboardFocusWithin) 
            { 
                //delegate the call using dispatcher, so all involved components do consume focus event, then i can commit the edit
                this.Dispatcher.BeginInvoke(new Action(() => 
                    {
                        //check if there is an edit in progress inside datagrid, which might have opened other dialog -
                        //in such case, the desigerView would loose keyboard focus and could ---- non-modal dialog (ie. intelisense window for ETB)
                        if (!this.ShouldIgnoreDataGridAutoCommit) 
                        {
                            if (null != this.variables1) 
                            { 
                                DataGridHelper.CommitPendingEdits(this.variables1.variableDataGrid);
                            } 
                            if (null != this.arguments1)
                            {
                                DataGridHelper.CommitPendingEdits(this.arguments1.argumentsDataGrid);
                            } 
                        }
                    }), DispatcherPriority.Input); 
            } 
            else
            { 
                ErrorReporting.ActiveDesignerView = this;
            }
        }
 
        //Suppress handling arrow keys in ScrollViewer
        void OnScrollContentKeyDown(object sender, KeyEventArgs e) 
        { 
            if (!e.Handled)
            { 
                if ((e.Key == Key.Up) || (e.Key == Key.Down) || (e.Key == Key.Left) || (e.Key == Key.Right))
                {
                    e.Handled = true;
                } 
            }
        } 
 
        protected override void OnKeyDown(KeyEventArgs e)
        { 
            //look up for unhandled Enter key events
            if (!e.Handled && Keyboard.Modifiers == ModifierKeys.None && e.OriginalSource is WorkflowViewElement)
            {
                switch (e.Key) 
                {
                    case Key.Enter: 
                        this.navigateToChildFunction((WorkflowViewElement)e.OriginalSource, true); 
                        break;
 
                    case Key.Back:
                        this.navigateToParentFunction((WorkflowViewElement)e.OriginalSource, true);
                        break;
                } 
            }
            base.OnKeyDown(e); 
        } 

        protected override void OnPreviewMouseWheel(MouseWheelEventArgs e) 
        {
            if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
            {
                this.zoomSlider.Value += e.Delta / scrollDeltaDivider; 
                e.Handled = true;
            } 
            else 
            {
                base.OnPreviewMouseWheel(e); 
            }
        }

        protected override void OnPreviewDragOver(DragEventArgs e) 
        {
            AutoScrollHelper.AutoScroll(e, this.scrollViewer); 
            base.OnPreviewDragOver(e); 
        }
 
        void OnDesignerSurfaceMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //user clicked on designer surface, somwhere around actual designer - try to select root designer
            if (e.OriginalSource == this.scrollViewer || e.OriginalSource == this.scrollableContent) 
            {
                //get root designer in given breadcrumb scope 
                var root = this.RootDesigner as WorkflowViewElement; 
                if (null != root)
                { 
                    //if Ctrl is pressed, handle toggling
                    if (Keyboard.Modifiers == ModifierKeys.Control)
                    {
                        Selection.Toggle(this.Context, root.ModelItem); 
                    }
                    //else, select the root 
                    else 
                    {
                        Selection.SelectOnly(this.Context, root.ModelItem); 
                    }
                    //update focused view element - keyboard focus is set to scrollview, but designer infrastructure requires updated
                    //FocusViewElement to reference root.
                    this.FocusedViewElement = root; 
                }
                e.Handled = true; 
            } 
        }
 
        static void OnActivitySchemaChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            DesignerView control = (DesignerView)dependencyObject;
            control.OnActivitySchemaChanged(); 
        }
 
        static void OnRootDesignerChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
        {
            DesignerView control = (DesignerView)dependencyObject; 
            control.OnRootDesignerChanged(e);
        }

        static void OnIsReadOnlyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
        {
            DesignerView designerView = (DesignerView)dependencyObject; 
            designerView.Context.Items.SetValue(new ReadOnlyState() { IsReadOnly = (bool)e.NewValue }); 
        }
 
        void HideBottomPane()
        {
            bottomPaneHeight = this.designerViewGrid.RowDefinitions[2].Height;
            this.designerViewGrid.RowDefinitions[2].Height = new GridLength(0); 
            this.splitter.Visibility = Visibility.Collapsed;
            this.bottomPanel.Visibility = Visibility.Collapsed; 
        } 

        void OnActivitySchemaChanged() 
        {
            if (null != this.ActivitySchema && typeof(ActivityBuilder).IsAssignableFrom(this.ActivitySchema.ItemType))
            {
                this.buttonArguments1.Visibility = Visibility.Visible; 
                Grid.SetColumn(importsStatusBarItem, 5);
            } 
            else 
            {
                this.buttonArguments1.Visibility = Visibility.Hidden; 
                this.buttonArguments1.IsChecked = false;
                Grid.SetColumn(importsStatusBarItem, 3);
            }
        } 

        private void OnBottomPanelClose(object sender, RoutedEventArgs e) 
        { 
            ToggleButton toggleButton = this.bottomPanel.Tag as ToggleButton;
            Fx.Assert(toggleButton != null, "toggleButton cannot be null"); 
            toggleButton.IsChecked = false;
        }

        void OnBreadCrumbClick(object sender, RoutedEventArgs e) 
        {
            //this method can be invoked two ways - left mouse click on element or key press 
            ListBoxItem listBoxItem = sender as ListBoxItem; 
            //handle only events for items which are actual model items
            if (null != listBoxItem && listBoxItem.Content is ModelItem) 
            {
                //determine which event are we handling
                KeyEventArgs keyArgs = e as KeyEventArgs;
                MouseButtonEventArgs mouseArgs = e as MouseButtonEventArgs; 
                //in case of key events - accept only Enter, in case of mouse events - i know it is left mouse button
                if ((null != keyArgs && keyArgs.Key == Key.Enter && Keyboard.Modifiers == ModifierKeys.None) || null != mouseArgs) 
                { 
                    //make selection new root designer
                    this.MakeRootDesigner((ModelItem)listBoxItem.Content); 
                    //mark event as handled
                    e.Handled = true;
                }
            } 
        }
 
        void OnBreadCrumbNavigation(object sender, KeyEventArgs e) 
        {
            //this method is invoked whenever user presses any key while breadcrumb has focus 
            ItemsControl breadcrumbItems = sender as ItemsControl;
            //i expect that there is at least one item in the collection, arrow key is pressed and no keyboard modifiers are active
            if (null != breadcrumbItems && breadcrumbItems.Items.Count > 0 && Keyboard.Modifiers == ModifierKeys.None && (e.Key == Key.Left || e.Key == Key.Right))
            { 
                //get first entry from collection
                UIElement first = (UIElement)breadcrumbItems.ItemContainerGenerator.ContainerFromIndex(0); 
                //get last entry from collection 
                UIElement last = (UIElement)breadcrumbItems.ItemContainerGenerator.ContainerFromIndex(breadcrumbItems.Items.Count - 1);
                //if last is selected, then set focus to the first, so Tab doesn't escape to other control 
                if (e.Key == Key.Right && last.IsKeyboardFocusWithin)
                {
                    first.Focus();
                    e.Handled = true; 
                }
                else if (e.Key == Key.Left && first.IsKeyboardFocusWithin) 
                { 
                    last.Focus();
                    e.Handled = true; 
                }
            }
        }
 
        void OnExtensionWindowClosing(object sender, ExtensionWindowClosingRoutedEventArgs e)
        { 
            e.Cancel = true; 
            e.Handled = true;
            ((ExtensionWindow)sender).IsEnabled = false; 
        }

        void OnRootDesignerChanged(DependencyPropertyChangedEventArgs e)
        { 
            WorkflowViewElement previousRoot = (WorkflowViewElement)e.OldValue;
            WorkflowViewElement currentRoot = (WorkflowViewElement)e.NewValue; 
            if (previousRoot != null) 
            {
                previousRoot.IsRootDesigner = false; 
            }
            if (currentRoot != null)
            {
                currentRoot.IsRootDesigner = true; 
            }
        } 
 
        [SuppressMessage(FxCop.Category.Usage, FxCop.Rule.ReviewUnusedParameters,
            Justification = "The parameters are defined by DependencyPropertyChangedEventHandler delegate")] 
        void OnMinimapVisibilityChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            ExtensionSurface.PlacementMode mode = ExtensionSurface.GetMode(this.miniMap);
            if (mode == ExtensionSurface.PlacementMode.Relative) 
            {
                ExtensionSurface.SetMode(this.miniMap, ExtensionSurface.PlacementMode.Absolute); 
            } 
        }
 
        void OnBottomPanelIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue == false)
            { 
                DependencyObject focusedElement = Keyboard.FocusedElement as DependencyObject;
                // Move the keyboard focus on a proper designer when the bottom panel is closed 
                if (focusedElement == null || focusedElement == sender || ((Visual)sender).IsAncestorOf(focusedElement)) 
                {
                    Keyboard.Focus(this.GetDesignerToFocus()); 
                }
            }
        }
 
        void OnToggleButtonCheckChanged(object sender, RoutedEventArgs e)
        { 
            ToggleButton button = sender as ToggleButton; 
            Fx.Assert(button != null, "Button cannot be null");
            ExtensionWindow window = button.Tag as ExtensionWindow; 
            if (null != window)
            {
                window.Visibility = button.IsChecked.Value ? Visibility.Visible : Visibility.Hidden;
            } 
            else
            { 
                UIElement uiElement = button.Tag as UIElement; 
                if (null != uiElement)
                { 
                    if (uiElement.Visibility == Visibility.Collapsed)
                    {
                        //remove the previous userControl
                        if (this.bottomPanel.Tag != null) 
                        {
                            ToggleButton toggleButton = this.bottomPanel.Tag as ToggleButton; 
                            Fx.Assert(toggleButton != null, "toggleButton should not be null"); 
                            if (button != toggleButton)
                            { 
                                toggleButton.IsChecked = false;
                            }
                        }
                        //add the new userControl 
                        this.bottomPanel.Visibility = Visibility.Visible;
                        this.bottomPanel.Tag = button; 
                        this.splitter.Visibility = Visibility.Visible; 
                        uiElement.Visibility = Visibility.Visible;
                        this.designerViewGrid.RowDefinitions[2].Height = bottomPaneHeight; 
                    }
                    else
                    {
                        //remove the current userControl 
                        this.bottomPanel.Tag = null;
                        HideBottomPane(); 
                        uiElement.Visibility = Visibility.Collapsed; 
                    }
                } 
            }
        }

        void OnZoomSliderValueChanged(object sender, RoutedPropertyChangedEventArgs e) 
        {
            if (this.ZoomFactor == 1) 
            { 
                TextOptions.SetTextFormattingMode(this.scrollableContent, TextFormattingMode.Display);
            } 
            else
            {
                TextOptions.SetTextFormattingMode(this.scrollableContent, TextFormattingMode.Ideal);
            } 
            this.scrollableContent.LayoutTransform = new ScaleTransform(this.ZoomFactor, this.ZoomFactor);
        } 
 
        void SetAsRootDesignerView(ModelItem root, bool setAsSelection)
        { 
            VirtualizedContainerService containerService = this.Context.Services.GetService();

            this.RootDesigner = null;
            //get the root view (route the call through virtualized container serivce, so Loaded and Unloaded events get hooked up) 
            VirtualizedContainerService.VirtualizingContainer rootContainer = (VirtualizedContainerService.VirtualizingContainer)containerService.GetContainer(root, null);
            rootContainer.Populate(); 
            this.RootDesigner = (WorkflowViewElement)rootContainer.Child; 

            if (setAsSelection) 
            {
                ModelItem selection = root;
                if (selectionMap.ContainsKey(root))
                { 
                    ModelItem prevSelection = selectionMap[root];
                    selection = null; 
                    if (prevSelection != null && ViewUtilities.IsViewVisible(prevSelection, root, context)) 
                    {
                        selection = prevSelection; 
                    }
                }
                if (selection != null)
                { 
                    selection.Focus();
                } 
                else 
                {
                    this.Context.Items.SetValue(new Selection()); 
                }
            }
        }
 
        private void SplitterDragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
        { 
            bottomPaneHeight = this.designerViewGrid.RowDefinitions[2].Height; 
        }
 

        Visual GetScreenShotVisual(out int imageWidth, out int imageHeight)
        {
            Rect size = VisualTreeHelper.GetDescendantBounds(this.designerPresenter); 
            imageWidth = (int)size.Width;
            imageHeight = (int)size.Height; 
            return this.designerPresenter; 
        }
 
        void CreateXPSDocument(string fileName)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            { 
                Package package = Package.Open(fs, FileMode.Create);
                XpsDocument document = new XpsDocument(package); 
                XpsDocumentWriter documentWriter = XpsDocument.CreateXpsDocumentWriter(document); 

                int imageWidth = (int)this.designerPresenter.DesiredSize.Width; 
                int imageHeight = (int)this.designerPresenter.DesiredSize.Height;

                PrintTicket ticket = new PrintTicket() { PageMediaSize = new PageMediaSize(imageWidth, imageHeight) };
                documentWriter.Write(this.designerPresenter, ticket); 
                document.Close();
                package.Close(); 
                fs.Flush(); 
            }
        } 

        void CreateImageFile(string fileName, Type encoderType)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Create)) 
            {
                BitmapEncoder encoder = (BitmapEncoder)Activator.CreateInstance(encoderType); 
                encoder.Frames.Add(BitmapFrame.Create(this.CreateScreenShot())); 
                encoder.Save(fs);
                fs.Close(); 
            }
        }

        BitmapFrame CreateScreenShot() 
        {
            const double DPI = 96.0; 
            int imageWidth; 
            int imageHeight;
            Visual visual = this.GetScreenShotVisual(out imageWidth, out imageHeight); 
            RenderTargetBitmap renderBitmap = new RenderTargetBitmap(imageWidth, imageHeight, DPI, DPI, PixelFormats.Pbgra32);
            renderBitmap.Render(visual);
            return BitmapFrame.Create(renderBitmap);
        } 

        public void OnReferenceUpdated(AssemblyName updatedReference, bool isAdded) 
        { 
            this.imports1.OnReferenceUpdated(updatedReference, isAdded);
        } 

        void OnVariablesCollectionChanged(object sender, RoutedEventArgs e)
        {
            this.buttonVariables1.IsChecked = true; 
        }
 
        void OnArgumentsCollectionChanged(object sender, RoutedEventArgs e) 
        {
            this.buttonArguments1.IsChecked = true; 
        }

        void ApplyShellBarItemVisibility(ShellBarItemVisibility visibility)
        { 
            //store user preferences
            this.shellBarItemVisibility = visibility; 
 
            // Analyze the enum
            bool isVariablesButtonVisible = ((ShellBarItemVisibility.Variables & visibility) == ShellBarItemVisibility.Variables); 
            bool isArgumentsButtonVisible = ((ShellBarItemVisibility.Arguments & visibility) == ShellBarItemVisibility.Arguments);
            bool isImportsButtonVisible = ((ShellBarItemVisibility.Imports & visibility) == ShellBarItemVisibility.Imports);

            // Apply the visibility constraints 
            this.variables1.VariableCollectionChanged -= this.OnVariablesCollectionChanged;
            this.variablesStatusBarItem.Visibility = isVariablesButtonVisible ? Visibility.Visible : Visibility.Collapsed; 
            if (isVariablesButtonVisible) 
            {
                this.variables1.VariableCollectionChanged += this.OnVariablesCollectionChanged; 
            }
            else if (this.variables1.IsVisible)
            {
                this.HideBottomPane(); 
                this.variables1.Visibility = Visibility.Collapsed;
            } 
 
            this.arguments1.ArgumentCollectionChanged -= this.OnArgumentsCollectionChanged;
            this.argumentsStatusBarItem.Visibility = isArgumentsButtonVisible ? Visibility.Visible : Visibility.Collapsed; 
            if (isArgumentsButtonVisible)
            {
                this.arguments1.ArgumentCollectionChanged += this.OnArgumentsCollectionChanged;
            } 
            else if (this.arguments1.IsVisible)
            { 
                this.HideBottomPane(); 
                this.arguments1.Visibility = Visibility.Collapsed;
            } 

            this.importsStatusBarItem.Visibility = isImportsButtonVisible ? Visibility.Visible : Visibility.Collapsed;
            if (!isImportsButtonVisible && (this.imports1.IsVisible))
            { 
                this.HideBottomPane();
                this.imports1.Visibility = Visibility.Collapsed; 
            } 

            // Align the buttons in the grid 
            int currentColumn = 1;
            if (isVariablesButtonVisible)
            {
                Grid.SetColumn(variablesStatusBarItem, currentColumn); 
                currentColumn += 2;
            } 
            if (isArgumentsButtonVisible) 
            {
                Grid.SetColumn(argumentsStatusBarItem, currentColumn); 
                currentColumn += 2;
            }
            if (isImportsButtonVisible)
            { 
                Grid.SetColumn(importsStatusBarItem, currentColumn);
                currentColumn += 2; 
            } 

            //handle zoom section items visibility 
            Visibility zoomVisibility = ((ShellBarItemVisibility.Zoom & visibility) == ShellBarItemVisibility.Zoom) ?
                Visibility.Visible : Visibility.Collapsed;

            this.zoomFitToScreenStatusBar.Visibility = zoomVisibility; 
            this.zoomIconStatusBar.Visibility = zoomVisibility;
            this.zoomPickerStatusBar.Visibility = zoomVisibility; 
            this.zoomSliderStatusBar.Visibility = zoomVisibility; 

            //handle minimap section visibility 
            this.minimapStatusBar.Visibility = ((ShellBarItemVisibility.MiniMap & visibility) == ShellBarItemVisibility.MiniMap) ?
                Visibility.Visible : Visibility.Collapsed;

            //if nothing is visible - hide entire status bar 
            this.shellBar.Visibility =
                (ShellBarItemVisibility.None == visibility || (ShellBarItemVisibility.Arguments == visibility && !this.arguments1.IsEnabled)) ? 
                Visibility.Collapsed : Visibility.Visible; 

        } 

        public void FlushState()
        {
            this.SaveDesignerStates(); 
        }
 
 
        void SaveDesignerStates()
        { 
            this.SaveBreadCrumbRoot();
            this.SaveSelection();
        }
 
        internal void RestoreDesignerStates()
        { 
            this.RestoreBreadCrumbRoot(); 
            this.RestoreSelection();
        } 

        void SaveSelection()
        {
            IWorkflowDesignerStorageService service = this.Context.Services.GetService(); 
            ModelTreeManager modelTreeManager = this.Context.Services.GetService();
            if (service != null && modelTreeManager != null) 
            { 
                Selection selection = this.Context.Items.GetValue();
                var selectionPathList = new List(); 
                foreach (ModelItem item in selection.SelectedObjects)
                {
                    if (item.Root == modelTreeManager.Root)
                    { 
                        selectionPathList.Add(item.GetModelPath());
                    } 
                } 
                if (service.ContainsKey(selectionKey))
                { 
                    service.SetData(selectionKey, selectionPathList);
                }
                else
                { 
                    service.AddData(selectionKey, selectionPathList);
                } 
            } 
        }
 
        void RestoreSelection()
        {
            IWorkflowDesignerStorageService service = this.Context.Services.GetService();
            ModelTreeManager modelTreeManager = this.Context.Services.GetService(); 
            if (service != null && service.ContainsKey(selectionKey) && modelTreeManager != null && modelTreeManager.Root != null)
            { 
                var selectionPathList = service.GetData(selectionKey) as List; 
                if (selectionPathList != null)
                { 
                    var modelItemList = new List();
                    foreach (string path in selectionPathList)
                    {
                        ModelItem item = ModelItemExtensions.GetModelItemFromPath(path, modelTreeManager.Root); 
                        if (item != null)
                        { 
                            modelItemList.Add(item); 
                        }
                    } 
                    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() =>
                    {
                        this.Context.Items.SetValue(new Selection(modelItemList));
                    })); 
                }
            } 
        } 

        void SaveBreadCrumbRoot() 
        {
            IWorkflowDesignerStorageService service = this.Context.Services.GetService();
            DesignerView designerView = this.Context.Services.GetService();
            if (service != null && designerView != null && designerView.RootDesigner != null) 
            {
                WorkflowViewElement rootDesigner = designerView.RootDesigner as WorkflowViewElement; 
                if (rootDesigner != null) 
                {
                    if (service.ContainsKey(breadCrumbRootKey)) 
                    {
                        service.SetData(breadCrumbRootKey, rootDesigner.ModelItem.GetModelPath());
                    }
                    else 
                    {
                        service.AddData(breadCrumbRootKey, rootDesigner.ModelItem.GetModelPath()); 
                    } 
                }
            } 
        }

        void RestoreBreadCrumbRoot()
        { 
            IWorkflowDesignerStorageService service = this.Context.Services.GetService();
            ModelTreeManager modelTreeManager = this.Context.Services.GetService(); 
            DesignerView designerView = this.context.Services.GetService(); 
            if (service != null && service.ContainsKey(breadCrumbRootKey) && modelTreeManager != null && modelTreeManager.Root != null && designerView != null)
            { 
                string path = service.GetData(breadCrumbRootKey) as string;
                if (path != null)
                {
                    ModelItem item = ModelItemExtensions.GetModelItemFromPath(path, modelTreeManager.Root); 
                    if (item != null)
                    { 
                        designerView.MakeRootDesigner(item); 
                    }
                } 
            }
        }

 
        //this class is used to convert zoom slider ticks to actual zoom percantage
        //the speced range of supported zoom values is between 25 % - 400% (with 25, 50, 100, 200 and 400 predefined steps) 
        //since increments are non linear, i use y = a(x*x) + c equation, to calculate zoom factor - zoom will be more glanular 
        //for small values, and more coarse for larger ones
        private sealed class ZoomToTicksConverter : IValueConverter 
        {
            const double minValue = 25;
            const double maxValue = 400;
 
            //predefined a value - calculated on assumption that maximum zoom value is 400%
            const double a = 0.15; 
            //predefined c value - calculated on assumption that minimum zoom value is 25% 
            const double c = 25;
            IValueConverter baseConverter; 

            DesignerView view;
            string zoomFitToScreenLabel;
            double[] keyboardZoomTicks; 

            internal ZoomToTicksConverter(DesignerView designer, Slider zoomSlider, ComboBox zoomPicker) 
            { 
                this.view = designer;
                this.zoomFitToScreenLabel = (this.view.TryFindResource("zoomFitToScreenLabel") as string) ?? "Fit to screen"; 
                //this.baseConverter = new ZoomPercentageConverter();
                //right now, we want to use our custom ZoomToPercantageConverter due to localization issues with WPF one
                this.baseConverter = new CustomZoomPercentageConverter();
 
                //initialize zoom slider
                zoomSlider.Minimum = 0; 
                zoomSlider.Maximum = 50; 
                zoomSlider.Ticks = new DoubleCollection(new double[] { 0, 10, 20, 30, 40, 50 });
 
                //set initial value - initially, zoom is set to 100%
                zoomSlider.Value = (double)this.ConvertBack(
                    this.baseConverter.Convert(100.0, typeof(string), null, CultureInfo.InvariantCulture), typeof(double), null, CultureInfo.InvariantCulture);
 
                //insert predefined values to zoomPicker - i use converter to percantage, to ensure text will be formated accordingly to user settings
                zoomPicker.ItemsSource = new object[] 
                    { 
                        this.baseConverter.Convert(25.0, typeof(string), null, CultureInfo.InvariantCulture),
                        this.baseConverter.Convert(50.0, typeof(string), null, CultureInfo.InvariantCulture), 
                        this.baseConverter.Convert(100.0, typeof(string), null, CultureInfo.InvariantCulture),
                        this.baseConverter.Convert(200.0, typeof(string), null, CultureInfo.InvariantCulture),
                        this.baseConverter.Convert(400.0, typeof(string), null, CultureInfo.InvariantCulture)
                    }; 

                //setup bindings 
                zoomPicker.SetBinding(ComboBox.SelectedItemProperty, new Binding() 
                {
                    Source = zoomSlider, 
                    Path = new PropertyPath(Slider.ValueProperty),
                    Converter = this
                });
 
                zoomPicker.SetBinding(ComboBox.TextProperty, new Binding()
                { 
                    Source = zoomSlider, 
                    Path = new PropertyPath(Slider.ValueProperty),
                    Converter = this 
                });

                this.keyboardZoomTicks = new double[]
                { 
                    (double)this.ConvertBack(
                        this.baseConverter.Convert(25.0, typeof(string), null, CultureInfo.InvariantCulture), typeof(double), null, CultureInfo.InvariantCulture), 
                    (double)this.ConvertBack( 
                        this.baseConverter.Convert(37.5, typeof(string), null, CultureInfo.InvariantCulture), typeof(double), null, CultureInfo.InvariantCulture),
                    (double)this.ConvertBack( 
                        this.baseConverter.Convert(50.0, typeof(string), null, CultureInfo.InvariantCulture), typeof(double), null, CultureInfo.InvariantCulture),
                    (double)this.ConvertBack(
                        this.baseConverter.Convert(75.0, typeof(string), null, CultureInfo.InvariantCulture), typeof(double), null, CultureInfo.InvariantCulture),
                    (double)this.ConvertBack( 
                        this.baseConverter.Convert(100.0, typeof(string), null, CultureInfo.InvariantCulture), typeof(double), null, CultureInfo.InvariantCulture),
                    (double)this.ConvertBack( 
                        this.baseConverter.Convert(150.0, typeof(string), null, CultureInfo.InvariantCulture), typeof(double), null, CultureInfo.InvariantCulture), 
                    (double)this.ConvertBack(
                        this.baseConverter.Convert(200.0, typeof(string), null, CultureInfo.InvariantCulture), typeof(double), null, CultureInfo.InvariantCulture), 
                    (double)this.ConvertBack(
                        this.baseConverter.Convert(300.0, typeof(string), null, CultureInfo.InvariantCulture), typeof(double), null, CultureInfo.InvariantCulture),
                    (double)this.ConvertBack(
                        this.baseConverter.Convert(400.0, typeof(string), null, CultureInfo.InvariantCulture), typeof(double), null, CultureInfo.InvariantCulture), 

                }; 
 
                this.view.zoomPicker.LostFocus += (s, e) =>
                { 
                    string text = this.Convert(this.view.zoomSlider.Value, typeof(string), null, CultureInfo.InvariantCulture) as string;
                    if (null != text)
                    {
                        this.view.zoomPicker.Text = string.Empty; 
                        this.view.zoomPicker.Text = text;
                    } 
                }; 

            } 

            double CalculateY(double x)
            {
                return ((x * x) * a) + c; 
            }
 
            double CalculateX(double y) 
            {
                return Math.Sqrt((y - c) / a); 
            }

            internal double ZoomFactor
            { 
                get
                { 
                    return this.CalculateY(this.view.zoomSlider.Value) / 100.0; 
                }
            } 

            public bool CanZoomIn()
            {
                return this.view.zoomSlider.Value < this.view.zoomSlider.Maximum; 
            }
 
            public void ZoomIn() 
            {
                double x = this.view.zoomSlider.Value; 
                for (int i = 0; i < this.keyboardZoomTicks.Length; ++i)
                {
                    if (x < this.keyboardZoomTicks[i])
                    { 
                        this.view.zoomSlider.Value = this.keyboardZoomTicks[i];
                        break; 
                    } 
                }
            } 

            public void ZoomOut()
            {
                double x = this.view.zoomSlider.Value; 
                for (int i = this.keyboardZoomTicks.Length - 1; i >= 0; --i)
                { 
                    if (x > this.keyboardZoomTicks[i]) 
                    {
                        this.view.zoomSlider.Value = this.keyboardZoomTicks[i]; 
                        break;
                    }
                }
            } 

            public bool CanZoomOut() 
            { 
                return this.view.zoomSlider.Value > this.view.zoomSlider.Minimum;
            } 

            public void FitToScreen()
            {
                double y1 = (this.view.scrollViewer.ViewportWidth / this.view.scrollableContent.ActualWidth) * 100.0; 
                double y2 = (this.view.scrollViewer.ViewportHeight / this.view.scrollableContent.ActualHeight) * 100.0;
                double y = Math.Min(maxValue, Math.Max(minValue, Math.Min(y1, y2))); 
                this.view.zoomSlider.Value = this.CalculateX(y); 
            }
 
            public void ResetZoom()
            {
                this.view.zoomSlider.Value = this.CalculateX(100.0);
            } 

            [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")]
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
            {
                if (null != value && value is double)
                {
                    try 
                    {
                        return this.baseConverter.Convert(this.CalculateY((double)value), targetType, parameter, culture); 
                    } 
                    catch (Exception e)
                    { 
                        System.Diagnostics.Debug.WriteLine(e.ToString());
                    }
                }
                return Binding.DoNothing; 
            }
 
            [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")] 

            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (null != value) 
                {
                    try 
                    { 
                        double y = 0.0;
                        if (string.Equals(this.zoomFitToScreenLabel, value)) 
                        {
                            double y1 = (this.view.scrollViewer.ViewportWidth / this.view.scrollableContent.ActualWidth) * 100.0;
                            double y2 = (this.view.scrollViewer.ViewportHeight / this.view.scrollableContent.ActualHeight) * 100.0;
                            y = Math.Min(maxValue, Math.Max(minValue, Math.Min(y1, y2))); 
                        }
                        else 
                        { 
                            y = (double)this.baseConverter.ConvertBack(value, targetType, parameter, culture);
                        } 
                        return this.CalculateX(y);
                    }
                    catch (Exception e)
                    { 
                        System.Diagnostics.Debug.WriteLine(e.ToString());
                    } 
                } 
                return Binding.DoNothing;
            } 
        }

        /// 
        /// CustomZoomPercentageConverter - used temporary instead of WPF provided ZoomToPercantageConverter due to the problems 
        /// in localized builds
        ///  
        private sealed class CustomZoomPercentageConverter : IValueConverter 
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
            {
                object result = DependencyProperty.UnsetValue;
                if (null != value)
                { 
                    double valueAsDouble = System.Convert.ToDouble(value, CultureInfo.InvariantCulture);
                    result = string.Format(CultureInfo.InvariantCulture, "{0}%", valueAsDouble.ToString("F", CultureInfo.InvariantCulture)).Replace(".00", ""); 
                } 
                return result;
            } 

            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                object result = DependencyProperty.UnsetValue; 
                if (null != value)
                { 
                    string valueAsString = value.ToString().Replace("%", "").Trim(); 
                    result = System.Convert.ToDouble(valueAsString, CultureInfo.InvariantCulture);
                } 
                return result;
            }
        }
 
        //BreadCrumbObjectSeparator - right now, this class has no functionality - object of this class is used as
        //a separator between different breadcrumb elements. however, i can imagine scenario when additional functionality 
        //is added here (i.e. similar to breadcrumb in Vista explorer) 
        sealed class BreadCrumbObjectSeparator
        { 
            //ItemType property - to avoid binding errors and make this object similar to ModelItem
            public Type ItemType
            {
                get { return typeof(BreadCrumbObjectSeparator); } 
            }
        } 
    } 

 
    internal sealed class ContextMenuIconProvider : IMultiValueConverter
    {
        //glyph image cache
        IDictionary, Image> glyphCache = new Dictionary, Image>(); 

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
        { 
            //get the menu item i'm reffering to
            var menuItem = values[0] as MenuItem; 
            //get the icon name as defined in /Resources dictionary
            var iconName = parameter as string;
            if (null != menuItem && !string.IsNullOrEmpty(iconName))
            { 
                Image glyph = null;
                //check if image has been used alreay - if yes - get it from cache. 
                if (!glyphCache.TryGetValue(new KeyValuePair(iconName, menuItem.IsEnabled), out glyph)) 
                {
                    glyph = this.CreateImage(iconName, menuItem.IsEnabled); 
                    //add it to the cache
                    glyphCache[new KeyValuePair(iconName, menuItem.IsEnabled)] = glyph;
                }
                //return glyph 
                return glyph;
            } 
            return Binding.DoNothing; 
        }
 
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw FxTrace.Exception.AsError(new NotSupportedException());
        } 

        Image CreateImage(string iconName, bool isEnabled) 
        { 
            //get uri to the image
            string uri = string.Format(CultureInfo.CurrentCulture, "pack://application:,,,/System.Activities.Presentation;component/Resources/{0}.png", iconName); 
            //open it
            var image = new BitmapImage(new Uri(uri, UriKind.Absolute));
            var format = PixelFormats.Bgra32;
            int width = image.PixelWidth; 
            int height = image.PixelHeight;
            int stride = ((width * format.BitsPerPixel) + 7) / 8; 
            var pixels = new uint[stride * height]; 
            //get image pixels
            image.CopyPixels(pixels, stride, 0); 

            //if menu item is disabled, convert image into gray scale
            if (!isEnabled)
            { 
                for (int i = 0; i < pixels.Length; ++i)
                { 
                    pixels[i] = this.MakePixelGray(pixels[i]); 
                }
            } 
            //create bitmap source
            var bitmapSource = BitmapSource.Create(width, height, image.DpiX, image.DpiY, format, null, pixels, stride);
            //pass it to the image
            return new Image() 
            {
                Source = bitmapSource, 
                Width = 16, 
                Height = 16
            }; 
        }

        uint MakePixelGray(uint pixel)
        { 
            byte blue = (byte)pixel;
            byte green = (byte)(pixel >> 8); 
            byte red = (byte)(pixel >> 16); 
            byte alpha = (byte)(pixel >> 24);
 
            byte gray = (byte)(((red * 77) + (green * 150) + (blue * 29) + 128) / 256);
            return (uint)(alpha << 24 | gray << 16 | gray << 8 | gray);
        }
    } 

    [SuppressMessage(FxCop.Category.Naming, FxCop.Rule.FlagsEnumsShouldHavePluralNames)] 
    [SuppressMessage(FxCop.Category.Usage, "CA2217", Justification = "This is enum value, we don't have enough enum values to fill 32 discrete values")] 
    [Flags]
    public enum ShellBarItemVisibility 
    {
        None = 0x0,
        Variables = 0x1,
        Arguments = 0x2, 
        Imports = 0x4,
        Zoom = 0x8, 
        MiniMap = 0x10, 
        All = -1
    } 

    internal sealed class ExpandAllCollapseAllToggleConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
        {
            //values[0] is the corresponding property - For ExpandAllButton - ShouldExpandAllProperty 
            //values[1] is the opposite property - For ExpandAllButton - ShouldCollapseAllProperty 
            return values[0];
        } 

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            //Whenever ExpandAll/CollapseAll toggle button state is changed, the opposite property is always reset. 
            return new object[] { value, false };
        } 
    } 
}

// 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