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

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

namespace System.Activities.Presentation.View 
{
    using System; 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Collections.Specialized; 
    using System.ComponentModel;
    using System.Globalization;
    using System.Linq;
    using System.Windows; 
    using System.Windows.Automation.Peers;
    using System.Windows.Controls; 
    using System.Windows.Data; 
    using System.Windows.Input;
    using System.Runtime; 
    using System.Windows.Automation;
    using System.Diagnostics.CodeAnalysis;
    using System.Windows.Threading;
    using System.Activities.Presentation.Hosting; 

    // This control presents a System.Type as textblock, which is editable on click, or F2. 
    public sealed partial class TypePresenter : ContentControl, INotifyPropertyChanged 
    {
        public static readonly DependencyProperty ContextProperty = 
            DependencyProperty.Register("Context",
            typeof(EditingContext),
            typeof(TypePresenter),
            new PropertyMetadata(new PropertyChangedCallback(OnContextChanged))); 

        public static readonly DependencyProperty AllowNullProperty = 
            DependencyProperty.Register("AllowNull", 
            typeof(bool),
            typeof(TypePresenter), 
            new PropertyMetadata(false, OnAllowNullChanged));

        public static readonly DependencyProperty BrowseTypeDirectlyProperty =
            DependencyProperty.Register("BrowseTypeDirectly", 
            typeof(bool),
            typeof(TypePresenter), 
            new PropertyMetadata(false, OnBrowseTypeDirectlyChanged)); 

        public static readonly DependencyProperty TypeProperty = 
            DependencyProperty.Register("Type",
            typeof(Type),
            typeof(TypePresenter),
            new PropertyMetadata(null, new PropertyChangedCallback(OnTypeChanged))); 

        public static readonly DependencyProperty LabelProperty = 
            DependencyProperty.Register("Label", 
            typeof(string),
            typeof(TypePresenter), 
            new PropertyMetadata(string.Empty));

        public static readonly DependencyProperty FilterProperty =
            DependencyProperty.Register("Filter", 
            typeof(Func),
            typeof(TypePresenter), 
            new PropertyMetadata(new PropertyChangedCallback(OnFilterChanged))); 

        static readonly DependencyPropertyKey TextPropertyKey =DependencyProperty.RegisterReadOnly( 
            "Text",
            typeof(string ),
            typeof(TypePresenter),
            new UIPropertyMetadata(null)); 

        public static readonly DependencyProperty TextProperty = TextPropertyKey.DependencyProperty; 
 
        public static readonly DependencyProperty MostRecentlyUsedTypesProperty =
            DependencyProperty.Register("MostRecentlyUsedTypes", 
            typeof(ObservableCollection),
            typeof(TypePresenter),
            new PropertyMetadata(TypePresenter.DefaultMostRecentlyUsedTypes, new PropertyChangedCallback(OnMostRecentlyUsedTypesPropertyChanged), new CoerceValueCallback(OnCoerceMostRecentlyUsedTypes)));
 
        public static readonly DependencyProperty CenterActivityTypeResolverDialogProperty =
            DependencyProperty.Register("CenterActivityTypeResolverDialog", 
            typeof(bool), 
            typeof(TypePresenter),
            new PropertyMetadata(true)); 

        public static readonly DependencyProperty CenterTypeBrowserDialogProperty =
            DependencyProperty.Register("CenterTypeBrowserDialog",
            typeof(bool), 
            typeof(TypePresenter),
            new PropertyMetadata(true)); 
 
        public static readonly RoutedEvent TypeBrowserOpenedEvent = EventManager.RegisterRoutedEvent(
            "TypeBrowserOpened", 
            RoutingStrategy.Bubble,
            typeof(RoutedEventHandler),
            typeof(TypePresenter));
 
        public static readonly RoutedEvent TypeBrowserClosedEvent = EventManager.RegisterRoutedEvent(
            "TypeBrowserClosed", 
            RoutingStrategy.Bubble, 
            typeof(RoutedEventHandler),
            typeof(TypePresenter)); 

        public static readonly RoutedEvent TypeChangedEvent = EventManager.RegisterRoutedEvent(
            "TypeChanged",
            RoutingStrategy.Bubble, 
            typeof(RoutedEventHandler),
            typeof(TypePresenter)); 
 
        static List defaultTypes = null;
        static ObservableCollection defaultMostRecentlyUsedTypes; 

        internal static List DefaultTypes
        {
            get 
            {
                if (defaultTypes == null) 
                { 
                    defaultTypes = new List
                    { 
                        typeof(Boolean),
                        typeof(Int32),
                        typeof(String),
                        typeof(Object), 
                    };
                } 
                return defaultTypes; 
            }
        } 

        public static ObservableCollection DefaultMostRecentlyUsedTypes
        {
            get 
            {
                if (defaultMostRecentlyUsedTypes == null) 
                { 
                    defaultMostRecentlyUsedTypes = new ObservableCollection(DefaultTypes);
                } 
                return defaultMostRecentlyUsedTypes;
            }
        }
 
        [SuppressMessage(FxCop.Category.Usage, FxCop.Rule.CollectionPropertiesShouldBeReadOnly,
            Justification = "Setter is provided to bind data on this property.")] 
        [Fx.Tag.KnownXamlExternal] 
        public ObservableCollection MostRecentlyUsedTypes
        { 
            get { return (ObservableCollection)GetValue(MostRecentlyUsedTypesProperty); }
            set { SetValue(MostRecentlyUsedTypesProperty, value); }
        }
 
        bool isMouseLeftButtonDown = true;
        Type lastSelection; 
        TypeWrapper nullTypeWrapper = null; 

        public TypePresenter() 
        {
            InitializeComponent();

            OnBrowseTypeDirectlyChanged(this, new DependencyPropertyChangedEventArgs( 
                TypePresenter.BrowseTypeDirectlyProperty, false, this.BrowseTypeDirectly));
            DisableEdit(); 
 
            this.typeComboBox.DropDownClosed += OnTypePresenterDropDownClosed;
            this.typeComboBox.PreviewLostKeyboardFocus += OnTypePresenterComboBoxPreviewLostKeyboardFocus; 
            this.typeComboBox.LostFocus += OnTypePresenterComboBoxLostFocus;
            this.typeComboBox.KeyDown += OnTypePresenterKeyDown;

            Binding textToType = new Binding(); 
            textToType.Converter = new TypeWrapperConverter(this);
            textToType.Source = this; 
            textToType.Path = new PropertyPath(TypeProperty); 
            this.typeComboBox.SetBinding(ComboBox.SelectedItemProperty, textToType);
            this.lastSelection = (Type)TypeProperty.DefaultMetadata.DefaultValue; 

            MultiBinding automationNameBinding = new MultiBinding();
            Binding labelBinding = new Binding("Label");
            labelBinding.Source = this; 
            automationNameBinding.Bindings.Add(labelBinding);
            Binding typeBinding = new Binding("Text"); 
            typeBinding.Source = this.typeTextBlock; 
            automationNameBinding.Bindings.Add(typeBinding);
            automationNameBinding.Converter = new AutomationNameConverter(); 
            this.SetBinding(AutomationProperties.NameProperty, automationNameBinding);

            this.Loaded += new RoutedEventHandler(TypePresenter_Loaded);
            this.Unloaded += new RoutedEventHandler(TypePresenter_Unloaded); 
        }
 
        void OnTypePresenterComboBoxPreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) 
        {
            if (this.typeComboBox.Visibility == Visibility.Visible && this.typeComboBox.IsDropDownOpen) 
            {
                e.Handled = true;
            }
        } 

        void OnTypePresenterComboBoxLostFocus(object sender, RoutedEventArgs e) 
        { 
            TypeWrapper tw = (TypeWrapper)this.typeComboBox.SelectedItem;
            if (tw != null) 
            {
                if (tw.Type == typeof(ArrayOf<>) || tw.Type == typeof(BrowseForType))
                {
                    SetComboBoxToLastSelection(); 
                }
            } 
        } 

        void SetComboBoxToLastSelection() 
        {
            if (this.lastSelection == null)
            {
                this.typeComboBox.SelectedIndex = this.typeComboBox.Items.IndexOf(this.NullTypeWrapper); 
            }
            else 
            { 
                for (int i = 0; i < this.typeComboBox.Items.Count; i++)
                { 
                    TypeWrapper typeWrapper = (TypeWrapper)this.typeComboBox.Items.GetItemAt(i);
                    if (typeWrapper.IsTypeDefinition && Type.Equals(this.lastSelection, typeWrapper.Type))
                    {
                        this.typeComboBox.SelectedIndex = i; 
 			break;
                    } 
                } 
            }
        } 

        public void FocusOnVisibleControl()
        {
            if (BrowseTypeDirectly) 
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() => 
                { 
                    Keyboard.Focus(this.typeTextBlock);
                })); 
            }
            else
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() => 
                {
                    Keyboard.Focus(this.typeComboBox); 
                })); 
            }
        } 


        void TypePresenter_Loaded(object sender, RoutedEventArgs e)
        { 
            //UnRegistering because of 137896: Inside tab control multiple Loaded events happen without an Unloaded event.
            this.MostRecentlyUsedTypes.CollectionChanged -= OnMostRecentlyUsedTypesChanged; 
            this.MostRecentlyUsedTypes.CollectionChanged += OnMostRecentlyUsedTypesChanged; 
            OnMostRecentlyUsedTypesChanged(this, null);
        } 

        void TypePresenter_Unloaded(object sender, RoutedEventArgs e)
        {
            this.MostRecentlyUsedTypes.CollectionChanged -= OnMostRecentlyUsedTypesChanged; 
        }
 
        public event RoutedEventHandler TypeBrowserOpened 
        {
            add { this.AddHandler(TypeBrowserOpenedEvent, value); } 
            remove { this.RemoveHandler(TypeBrowserOpenedEvent, value); }
        }

        public event RoutedEventHandler TypeBrowserClosed 
        {
            add { this.AddHandler(TypeBrowserClosedEvent, value); } 
            remove { this.RemoveHandler(TypeBrowserClosedEvent, value); } 
        }
 
        public event RoutedEventHandler TypeChanged
        {
            add { this.AddHandler(TypeChangedEvent, value); }
            remove { this.RemoveHandler(TypeChangedEvent, value); } 
        }
 
        public event PropertyChangedEventHandler PropertyChanged; 

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

        public string Label 
        {
            get { return (string)GetValue(LabelProperty); } 
            set { SetValue(LabelProperty, value); } 
        }
 
        [Fx.Tag.KnownXamlExternal]
        public Func Filter
        {
            get { return (Func)GetValue(FilterProperty); } 
            set { SetValue(FilterProperty, value); }
        } 
 
        public bool CenterActivityTypeResolverDialog
        { 
            get { return (bool)GetValue(CenterActivityTypeResolverDialogProperty); }
            set { SetValue(CenterActivityTypeResolverDialogProperty, value); }
        }
 
        public bool CenterTypeBrowserDialog
        { 
            get { return (bool)GetValue(CenterTypeBrowserDialogProperty); } 
            set { SetValue(CenterTypeBrowserDialogProperty, value); }
        } 

        internal TypeWrapper NullTypeWrapper
        {
            get 
            {
                if (this.nullTypeWrapper == null) 
                { 
                    this.nullTypeWrapper = new TypeWrapper(NullString, "Null", null);
                } 
                return this.nullTypeWrapper;
            }
        }
 
        public string Text
        { 
            get { return (string)GetValue(TextProperty); } 
            private set { SetValue(TextPropertyKey, value); }
        } 


        public IEnumerable Items
        { 
            get
            { 
                if (AllowNull) 
                {
                    yield return this.NullTypeWrapper; 
                }
                foreach (Type type in this.MostRecentlyUsedTypes)
                {
                    if (type != null) 
                    {
                        if (this.Filter == null 
                           || this.Filter(type)) 
                        {
                            yield return new TypeWrapper(type); 
                        }
                    }
                }
 
                //display Array of [T] option
                if (this.Filter == null 
                    || this.Filter(typeof(Array))) 
                {
                    yield return new TypeWrapper("Array of [T]", "T[]", typeof(ArrayOf<>)); 
                }
                //display "Browse for types" option
                //if there are referenced and local assembly info in Editing context (inside VS), type browser will show those assemblies,
                //otherwise (standalone), type browser will just show all loaded assemblies in current appdomain 
                yield return new TypeWrapper(BrowseTypeString, "BrowseForTypes", typeof(BrowseForType));
            } 
        } 

        public bool BrowseTypeDirectly 
        {
            get { return (bool)GetValue(BrowseTypeDirectlyProperty); }
            set { SetValue(BrowseTypeDirectlyProperty, value); }
        } 

 
        [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "By design.")] 
        public Type Type
        { 
            get { return (Type)GetValue(TypeProperty); }
            set { SetValue(TypeProperty, value); }
        }
 
        public string TypeName
        { 
            get 
            {
                string typeName = string.Empty; 
                this.ToolTip = null;
                if (null != this.Type)
                {
                    if (TypePresenter.DefaultTypes.Contains(this.Type)) 
                    {
                        typeName = this.Type.Name; 
                    } 
                    else
                    { 
                        typeName = TypeNameHelper.GetDisplayName(this.Type, true);
                    }
                    this.ToolTip = typeName;
                } 
                return typeName;
            } 
        } 

        AssemblyContextControlItem AssemblyContext 
        {
            get
            {
                return (null != Context ? Context.Items.GetValue() : null); 
            }
        } 
 
        string BrowseTypeString
        { 
            get { return (string)this.FindResource("BrowseTypeString"); }
        }

        string NullString 
        {
            get { return "(null)"; } 
        } 

        protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer() 
        {
            return new UIElementAutomationPeer(this);
        }
 
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        { 
            base.OnMouseLeftButtonDown(e); 
            this.isMouseLeftButtonDown = true;
            e.Handled = true; 
        }

        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        { 
            base.OnMouseLeftButtonUp(e);
            if (this.isMouseLeftButtonDown) 
            { 
                if (this.BrowseTypeDirectly)
                { 
                    HandleBrowseType();
                }
                else
                { 
                    this.EnableEdit();
                } 
            } 
            this.isMouseLeftButtonDown = false;
            e.Handled = true; 
        }

        protected override void OnPreviewKeyDown(KeyEventArgs e)
        { 
            base.OnPreviewKeyDown(e);
            if (IsPreviewKey(e.Key)) 
            { 
                Preview();
            } 
        }

        internal static bool IsPreviewKey(Key key)
        { 
            return (key == Key.F2 || key == Key.Space || key == Key.Enter);
        } 
 
        internal void Preview()
        { 
            if (this.BrowseTypeDirectly)
            {
                HandleBrowseType();
            } 
            else
            { 
                this.EnableEdit(); 
            }
        } 

        static void OnContextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            TypePresenter ctrl = (TypePresenter)sender; 
            ctrl.OnItemsChanged();
        } 
 
        static void OnAllowNullChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        { 
            TypePresenter ctrl = (TypePresenter)sender;
            ctrl.OnItemsChanged();
        }
 
        static void OnBrowseTypeDirectlyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        { 
            TypePresenter ctrl = (TypePresenter)sender; 
            if (!(bool)args.NewValue)
            { 
                ctrl.typeComboBox.Visibility = Visibility.Visible;
                ctrl.typeTextBlock.Visibility = Visibility.Collapsed;
                ctrl.Focusable = false;
            } 
            else
            { 
                ctrl.typeComboBox.Visibility = Visibility.Collapsed; 
                ctrl.typeTextBlock.Visibility = Visibility.Visible;
                ctrl.Focusable = true; 
            }
        }

        static void OnTypeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) 
        {
            TypePresenter ctrl = (TypePresenter)sender; 
            ctrl.lastSelection = (Type)args.NewValue; 

            if (null != ctrl.PropertyChanged) 
            {
                ctrl.PropertyChanged(ctrl, new PropertyChangedEventArgs("TypeName"));
            }
 
            if (null == ctrl.lastSelection)
            { 
                ctrl.typeComboBox.SelectedIndex = ctrl.typeComboBox.Items.IndexOf(ctrl.NullTypeWrapper); 
            }
 
            ctrl.Text = ctrl.TypeName;
            ctrl.RaiseEvent(new RoutedEventArgs(TypePresenter.TypeChangedEvent, ctrl));
        }
 
        static void OnFilterChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        { 
            TypePresenter ctrl = (TypePresenter)sender; 
            if (null != ctrl.PropertyChanged)
            { 
                ctrl.PropertyChanged(ctrl, new PropertyChangedEventArgs("Items"));
            }
        }
 
        static void OnMostRecentlyUsedTypesPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        { 
            TypePresenter ctrl = (TypePresenter)sender; 
            ((ObservableCollection)args.NewValue).CollectionChanged += ctrl.OnMostRecentlyUsedTypesChanged;
            ((ObservableCollection)args.OldValue).CollectionChanged -= ctrl.OnMostRecentlyUsedTypesChanged; 

            ctrl.OnItemsChanged();
        }
 
        static object OnCoerceMostRecentlyUsedTypes(DependencyObject sender, object value)
        { 
            if (value != null) 
            {
                return value; 
            }
            else
            {
                return TypePresenter.DefaultMostRecentlyUsedTypes; 
            }
        } 
 
        void DisableEdit()
        { 
            if (BrowseTypeDirectly)
            {
                this.typeTextBlock.Visibility = Visibility.Visible;
                this.typeComboBox.Visibility = Visibility.Collapsed; 
            }
        } 
 
        void EnableEdit()
        { 
            if (BrowseTypeDirectly)
            {
                this.typeTextBlock.Visibility = Visibility.Collapsed;
                this.typeComboBox.Visibility = Visibility.Visible; 
            }
            this.typeComboBox.Focus(); 
        } 

        // return true if KeyDownEvent should be set to handled 
        bool HandleBrowseType()
        {
            bool retval = false;
            TypeWrapper wrapper = (TypeWrapper)this.typeComboBox.SelectedItem; 

            if ((wrapper != null && !wrapper.IsTypeDefinition) 
                || this.BrowseTypeDirectly) 
            {
                Type result = null; 
                bool? dialogResult = true;
                bool typeIsArray = true;
                bool fireEvent = false;
                //handle choosing an array of T 
                if (wrapper != null && typeof(ArrayOf<>) == wrapper.Type)
                { 
                    fireEvent = true; 
                    this.RaiseEvent(new RoutedEventArgs(TypePresenter.TypeBrowserOpenedEvent, this));
                    result = wrapper.Type; 
                }
                else if (wrapper != null && wrapper.DisplayName == NullString)
                {
                    this.Type = null; 
                    return false;
                } 
                else 
                {
                    retval = true; 
                    fireEvent = true;
                    this.RaiseEvent(new RoutedEventArgs(TypePresenter.TypeBrowserOpenedEvent, this));
                    TypeBrowser browser = new TypeBrowser(AssemblyContext, this.Context, this.Filter);
                    SetWindowOwner(browser); 
                    if (this.CenterTypeBrowserDialog)
                    { 
                        browser.WindowStartupLocation = WindowStartupLocation.CenterScreen; 
                    }
                    dialogResult = browser.ShowDialog(); 
                    if (dialogResult.HasValue && dialogResult.Value)
                    {
                        result = browser.ConcreteType;
                    } 

                    typeIsArray = false; 
                } 

                if (dialogResult.HasValue && dialogResult.Value) 
                {
                    //user may have chosen generic type (IList)
                    if (result.IsGenericTypeDefinition)
                    { 
                        retval = true;
                        ActivityTypeResolver wnd = new ActivityTypeResolver(); 
                        SetWindowOwner(wnd); 
                        wnd.Context = this.Context;
                        wnd.EditedType = result; 
                        if (this.CenterActivityTypeResolverDialog)
                        {
                            wnd.WindowStartupLocation = WindowStartupLocation.CenterScreen;
                        } 

                        result = (true == wnd.ShowDialog() ? wnd.ConcreteType : null); 
                    } 
                    //if we have a type
                    if (null != result) 
                    {
                        //if we have a ArrayOf, create actual array type
                        if (typeIsArray)
                        { 
                            result = result.GetGenericArguments()[0].MakeArrayType();
                        } 
                        //add it to the cache 
                        if (!MostRecentlyUsedTypes.Any(p => Type.Equals(p, result)))
                        { 
                            MostRecentlyUsedTypes.Add(result);
                        }

                        //and return updated result 
                        this.Type = result;
                    } 
                    else 
                    {
                        this.Type = this.lastSelection; 
                    }

                    BindingExpression binding = this.typeComboBox.GetBindingExpression(ComboBox.SelectedItemProperty);
                    binding.UpdateTarget(); 
                }
                else 
                { 
                    SetComboBoxToLastSelection();
                } 
                if (fireEvent)
                {
                    this.RaiseEvent(new RoutedEventArgs(TypePresenter.TypeBrowserClosedEvent, this));
                } 
            }
 
            return retval; 
        }
 
        void OnMostRecentlyUsedTypesChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            OnItemsChanged();
        } 

        void OnItemsChanged() 
        { 
            if (null != PropertyChanged)
            { 
                PropertyChanged(this, new PropertyChangedEventArgs("Items"));
            }
        }
 
        void OnTypePresenterDropDownClosed(object sender, EventArgs e)
        { 
            HandleBrowseType(); 
            DisableEdit();
            if (!this.BrowseTypeDirectly) 
            {
                this.typeComboBox.Focus();
            }
            else 
            {
                this.Focus(); 
            } 
        }
 
        void OnTypePresenterKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            { 
                if (HandleBrowseType())
                { 
                    e.Handled = true; 
                }
                DisableEdit(); 

                FocusOnVisibleControl();
            }
        } 

        void OnTypePresenterLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) 
        { 
            if (!(e.NewFocus == this))
            { 
                if (!(this.typeComboBox.IsDropDownOpen || this.typeComboBox.IsSelectionBoxHighlighted))
                {
                    DisableEdit();
                } 
            }
        } 
 
        void SetWindowOwner(Window wnd)
        { 
            if (null != this.Context)
            {
                WindowHelperService service = this.Context.Services.GetService();
                if (null != service) 
                {
                    service.TrySetWindowOwner(this, wnd); 
                } 
            }
        } 

        // internal converter class - assign a meaningful AutomationProperties.Name to the type presenter
        // AutomationProperties.Name = Label + the string displayed on the TypePresenter
        sealed class AutomationNameConverter : IMultiValueConverter 
        {
            public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
            { 
                Fx.Assert(values.Length == 2, "There should be exactly 2 values");
                return (string)values[0] + ": " + (string)values[1]; 
            }

            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
            { 
                Fx.Assert("Not supported!");
                return null; 
            } 
        }
    } 

    [Fx.Tag.XamlVisible(false)]
    public sealed class TypeWrapper
    { 
        string displayName;
        bool isTypeDefinition; 
        Type type; 

        internal TypeWrapper(Type type) 
        {
            this.type = type;
            this.isTypeDefinition = true;
            this.Tag = DisplayName; 
        }
 
        internal TypeWrapper(string text, string tag, Type type) 
        {
            this.displayName = text; 
            this.isTypeDefinition = false;
            this.Tag = tag;
            this.type = type;
        } 

        public string DisplayName 
        { 
            get
            { 
                if (this.isTypeDefinition)
                {
                    if (TypePresenter.DefaultTypes.Contains(this.type))
                    { 
                        return this.type.Name;
                    } 
 
                    return TypeNameHelper.GetDisplayName(this.Type, true);
                } 
                return this.displayName;
            }
        }
 
        public bool IsTypeDefinition
        { 
            get { return this.isTypeDefinition; } 
        }
 
        public object Tag
        {
            get;
            private set; 
        }
 
        [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "By design.")] 
        public Type Type
        { 
            get { return this.type; }
        }

        public override string ToString() 
        {
            return Tag as string; 
        } 

        public override bool Equals(object obj) 
        {
            TypeWrapper that = obj as TypeWrapper;
            if (that == null)
            { 
                return false;
            } 
            if (that.IsTypeDefinition ^ this.IsTypeDefinition) 
            {
                return false; 
            }
            if (this.displayName != that.displayName)
            {
                return false; 
            }
            return object.Equals(this.Type, that.Type); 
        } 

        public override int GetHashCode() 
        {
            if (this.Type != null)
            {
                return this.Type.GetHashCode(); 
            }
            else 
            { 
                return base.GetHashCode();
            } 
        }
    }

    sealed class ArrayOf 
    {
    } 
 
    sealed class BrowseForType
    { 
    }

    // internal converter class - keeps link between display friendly string representation of types
    // and actual underlying system type. 
    sealed class TypeWrapperConverter : IValueConverter
    { 
        TypePresenter typePresenter; 

        //ctor - initialzied with list of loaded types into the presenter 
        internal TypeWrapperConverter(TypePresenter typePresenter)
        {
            this.typePresenter = typePresenter;
        } 

        //convert from System.Type to TypeWrapper (display friendly) 
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
        {
            if (null != value) 
            {
                //lookup in loaded types if type is already there

                //if no - add it to collection - may be reused later 
                if (null == this.typePresenter.MostRecentlyUsedTypes.SingleOrDefault(p => Type.Equals(p, (Type)value)))
                { 
                    this.typePresenter.MostRecentlyUsedTypes.Add((Type)value); 
                }
 
                return new TypeWrapper((Type)value);
            }
            else
            { 
                return this.typePresenter.NullTypeWrapper;
            } 
        } 

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
        {
            //convert back - just get the Type property of the wrapper object
            TypeWrapper typeWrapper = value as TypeWrapper;
 
            if (typeWrapper == this.typePresenter.NullTypeWrapper)
            { 
                return null; 
            }
 
            if (null != typeWrapper && null != typeWrapper.Type && typeof(ArrayOf<>) != typeWrapper.Type && typeof(BrowseForType) != typeWrapper.Type)
            {
                return typeWrapper.Type;
            } 

            return Binding.DoNothing; 
        } 
    }
} 

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

namespace System.Activities.Presentation.View 
{
    using System; 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Collections.Specialized; 
    using System.ComponentModel;
    using System.Globalization;
    using System.Linq;
    using System.Windows; 
    using System.Windows.Automation.Peers;
    using System.Windows.Controls; 
    using System.Windows.Data; 
    using System.Windows.Input;
    using System.Runtime; 
    using System.Windows.Automation;
    using System.Diagnostics.CodeAnalysis;
    using System.Windows.Threading;
    using System.Activities.Presentation.Hosting; 

    // This control presents a System.Type as textblock, which is editable on click, or F2. 
    public sealed partial class TypePresenter : ContentControl, INotifyPropertyChanged 
    {
        public static readonly DependencyProperty ContextProperty = 
            DependencyProperty.Register("Context",
            typeof(EditingContext),
            typeof(TypePresenter),
            new PropertyMetadata(new PropertyChangedCallback(OnContextChanged))); 

        public static readonly DependencyProperty AllowNullProperty = 
            DependencyProperty.Register("AllowNull", 
            typeof(bool),
            typeof(TypePresenter), 
            new PropertyMetadata(false, OnAllowNullChanged));

        public static readonly DependencyProperty BrowseTypeDirectlyProperty =
            DependencyProperty.Register("BrowseTypeDirectly", 
            typeof(bool),
            typeof(TypePresenter), 
            new PropertyMetadata(false, OnBrowseTypeDirectlyChanged)); 

        public static readonly DependencyProperty TypeProperty = 
            DependencyProperty.Register("Type",
            typeof(Type),
            typeof(TypePresenter),
            new PropertyMetadata(null, new PropertyChangedCallback(OnTypeChanged))); 

        public static readonly DependencyProperty LabelProperty = 
            DependencyProperty.Register("Label", 
            typeof(string),
            typeof(TypePresenter), 
            new PropertyMetadata(string.Empty));

        public static readonly DependencyProperty FilterProperty =
            DependencyProperty.Register("Filter", 
            typeof(Func),
            typeof(TypePresenter), 
            new PropertyMetadata(new PropertyChangedCallback(OnFilterChanged))); 

        static readonly DependencyPropertyKey TextPropertyKey =DependencyProperty.RegisterReadOnly( 
            "Text",
            typeof(string ),
            typeof(TypePresenter),
            new UIPropertyMetadata(null)); 

        public static readonly DependencyProperty TextProperty = TextPropertyKey.DependencyProperty; 
 
        public static readonly DependencyProperty MostRecentlyUsedTypesProperty =
            DependencyProperty.Register("MostRecentlyUsedTypes", 
            typeof(ObservableCollection),
            typeof(TypePresenter),
            new PropertyMetadata(TypePresenter.DefaultMostRecentlyUsedTypes, new PropertyChangedCallback(OnMostRecentlyUsedTypesPropertyChanged), new CoerceValueCallback(OnCoerceMostRecentlyUsedTypes)));
 
        public static readonly DependencyProperty CenterActivityTypeResolverDialogProperty =
            DependencyProperty.Register("CenterActivityTypeResolverDialog", 
            typeof(bool), 
            typeof(TypePresenter),
            new PropertyMetadata(true)); 

        public static readonly DependencyProperty CenterTypeBrowserDialogProperty =
            DependencyProperty.Register("CenterTypeBrowserDialog",
            typeof(bool), 
            typeof(TypePresenter),
            new PropertyMetadata(true)); 
 
        public static readonly RoutedEvent TypeBrowserOpenedEvent = EventManager.RegisterRoutedEvent(
            "TypeBrowserOpened", 
            RoutingStrategy.Bubble,
            typeof(RoutedEventHandler),
            typeof(TypePresenter));
 
        public static readonly RoutedEvent TypeBrowserClosedEvent = EventManager.RegisterRoutedEvent(
            "TypeBrowserClosed", 
            RoutingStrategy.Bubble, 
            typeof(RoutedEventHandler),
            typeof(TypePresenter)); 

        public static readonly RoutedEvent TypeChangedEvent = EventManager.RegisterRoutedEvent(
            "TypeChanged",
            RoutingStrategy.Bubble, 
            typeof(RoutedEventHandler),
            typeof(TypePresenter)); 
 
        static List defaultTypes = null;
        static ObservableCollection defaultMostRecentlyUsedTypes; 

        internal static List DefaultTypes
        {
            get 
            {
                if (defaultTypes == null) 
                { 
                    defaultTypes = new List
                    { 
                        typeof(Boolean),
                        typeof(Int32),
                        typeof(String),
                        typeof(Object), 
                    };
                } 
                return defaultTypes; 
            }
        } 

        public static ObservableCollection DefaultMostRecentlyUsedTypes
        {
            get 
            {
                if (defaultMostRecentlyUsedTypes == null) 
                { 
                    defaultMostRecentlyUsedTypes = new ObservableCollection(DefaultTypes);
                } 
                return defaultMostRecentlyUsedTypes;
            }
        }
 
        [SuppressMessage(FxCop.Category.Usage, FxCop.Rule.CollectionPropertiesShouldBeReadOnly,
            Justification = "Setter is provided to bind data on this property.")] 
        [Fx.Tag.KnownXamlExternal] 
        public ObservableCollection MostRecentlyUsedTypes
        { 
            get { return (ObservableCollection)GetValue(MostRecentlyUsedTypesProperty); }
            set { SetValue(MostRecentlyUsedTypesProperty, value); }
        }
 
        bool isMouseLeftButtonDown = true;
        Type lastSelection; 
        TypeWrapper nullTypeWrapper = null; 

        public TypePresenter() 
        {
            InitializeComponent();

            OnBrowseTypeDirectlyChanged(this, new DependencyPropertyChangedEventArgs( 
                TypePresenter.BrowseTypeDirectlyProperty, false, this.BrowseTypeDirectly));
            DisableEdit(); 
 
            this.typeComboBox.DropDownClosed += OnTypePresenterDropDownClosed;
            this.typeComboBox.PreviewLostKeyboardFocus += OnTypePresenterComboBoxPreviewLostKeyboardFocus; 
            this.typeComboBox.LostFocus += OnTypePresenterComboBoxLostFocus;
            this.typeComboBox.KeyDown += OnTypePresenterKeyDown;

            Binding textToType = new Binding(); 
            textToType.Converter = new TypeWrapperConverter(this);
            textToType.Source = this; 
            textToType.Path = new PropertyPath(TypeProperty); 
            this.typeComboBox.SetBinding(ComboBox.SelectedItemProperty, textToType);
            this.lastSelection = (Type)TypeProperty.DefaultMetadata.DefaultValue; 

            MultiBinding automationNameBinding = new MultiBinding();
            Binding labelBinding = new Binding("Label");
            labelBinding.Source = this; 
            automationNameBinding.Bindings.Add(labelBinding);
            Binding typeBinding = new Binding("Text"); 
            typeBinding.Source = this.typeTextBlock; 
            automationNameBinding.Bindings.Add(typeBinding);
            automationNameBinding.Converter = new AutomationNameConverter(); 
            this.SetBinding(AutomationProperties.NameProperty, automationNameBinding);

            this.Loaded += new RoutedEventHandler(TypePresenter_Loaded);
            this.Unloaded += new RoutedEventHandler(TypePresenter_Unloaded); 
        }
 
        void OnTypePresenterComboBoxPreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) 
        {
            if (this.typeComboBox.Visibility == Visibility.Visible && this.typeComboBox.IsDropDownOpen) 
            {
                e.Handled = true;
            }
        } 

        void OnTypePresenterComboBoxLostFocus(object sender, RoutedEventArgs e) 
        { 
            TypeWrapper tw = (TypeWrapper)this.typeComboBox.SelectedItem;
            if (tw != null) 
            {
                if (tw.Type == typeof(ArrayOf<>) || tw.Type == typeof(BrowseForType))
                {
                    SetComboBoxToLastSelection(); 
                }
            } 
        } 

        void SetComboBoxToLastSelection() 
        {
            if (this.lastSelection == null)
            {
                this.typeComboBox.SelectedIndex = this.typeComboBox.Items.IndexOf(this.NullTypeWrapper); 
            }
            else 
            { 
                for (int i = 0; i < this.typeComboBox.Items.Count; i++)
                { 
                    TypeWrapper typeWrapper = (TypeWrapper)this.typeComboBox.Items.GetItemAt(i);
                    if (typeWrapper.IsTypeDefinition && Type.Equals(this.lastSelection, typeWrapper.Type))
                    {
                        this.typeComboBox.SelectedIndex = i; 
 			break;
                    } 
                } 
            }
        } 

        public void FocusOnVisibleControl()
        {
            if (BrowseTypeDirectly) 
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() => 
                { 
                    Keyboard.Focus(this.typeTextBlock);
                })); 
            }
            else
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() => 
                {
                    Keyboard.Focus(this.typeComboBox); 
                })); 
            }
        } 


        void TypePresenter_Loaded(object sender, RoutedEventArgs e)
        { 
            //UnRegistering because of 137896: Inside tab control multiple Loaded events happen without an Unloaded event.
            this.MostRecentlyUsedTypes.CollectionChanged -= OnMostRecentlyUsedTypesChanged; 
            this.MostRecentlyUsedTypes.CollectionChanged += OnMostRecentlyUsedTypesChanged; 
            OnMostRecentlyUsedTypesChanged(this, null);
        } 

        void TypePresenter_Unloaded(object sender, RoutedEventArgs e)
        {
            this.MostRecentlyUsedTypes.CollectionChanged -= OnMostRecentlyUsedTypesChanged; 
        }
 
        public event RoutedEventHandler TypeBrowserOpened 
        {
            add { this.AddHandler(TypeBrowserOpenedEvent, value); } 
            remove { this.RemoveHandler(TypeBrowserOpenedEvent, value); }
        }

        public event RoutedEventHandler TypeBrowserClosed 
        {
            add { this.AddHandler(TypeBrowserClosedEvent, value); } 
            remove { this.RemoveHandler(TypeBrowserClosedEvent, value); } 
        }
 
        public event RoutedEventHandler TypeChanged
        {
            add { this.AddHandler(TypeChangedEvent, value); }
            remove { this.RemoveHandler(TypeChangedEvent, value); } 
        }
 
        public event PropertyChangedEventHandler PropertyChanged; 

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

        public string Label 
        {
            get { return (string)GetValue(LabelProperty); } 
            set { SetValue(LabelProperty, value); } 
        }
 
        [Fx.Tag.KnownXamlExternal]
        public Func Filter
        {
            get { return (Func)GetValue(FilterProperty); } 
            set { SetValue(FilterProperty, value); }
        } 
 
        public bool CenterActivityTypeResolverDialog
        { 
            get { return (bool)GetValue(CenterActivityTypeResolverDialogProperty); }
            set { SetValue(CenterActivityTypeResolverDialogProperty, value); }
        }
 
        public bool CenterTypeBrowserDialog
        { 
            get { return (bool)GetValue(CenterTypeBrowserDialogProperty); } 
            set { SetValue(CenterTypeBrowserDialogProperty, value); }
        } 

        internal TypeWrapper NullTypeWrapper
        {
            get 
            {
                if (this.nullTypeWrapper == null) 
                { 
                    this.nullTypeWrapper = new TypeWrapper(NullString, "Null", null);
                } 
                return this.nullTypeWrapper;
            }
        }
 
        public string Text
        { 
            get { return (string)GetValue(TextProperty); } 
            private set { SetValue(TextPropertyKey, value); }
        } 


        public IEnumerable Items
        { 
            get
            { 
                if (AllowNull) 
                {
                    yield return this.NullTypeWrapper; 
                }
                foreach (Type type in this.MostRecentlyUsedTypes)
                {
                    if (type != null) 
                    {
                        if (this.Filter == null 
                           || this.Filter(type)) 
                        {
                            yield return new TypeWrapper(type); 
                        }
                    }
                }
 
                //display Array of [T] option
                if (this.Filter == null 
                    || this.Filter(typeof(Array))) 
                {
                    yield return new TypeWrapper("Array of [T]", "T[]", typeof(ArrayOf<>)); 
                }
                //display "Browse for types" option
                //if there are referenced and local assembly info in Editing context (inside VS), type browser will show those assemblies,
                //otherwise (standalone), type browser will just show all loaded assemblies in current appdomain 
                yield return new TypeWrapper(BrowseTypeString, "BrowseForTypes", typeof(BrowseForType));
            } 
        } 

        public bool BrowseTypeDirectly 
        {
            get { return (bool)GetValue(BrowseTypeDirectlyProperty); }
            set { SetValue(BrowseTypeDirectlyProperty, value); }
        } 

 
        [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "By design.")] 
        public Type Type
        { 
            get { return (Type)GetValue(TypeProperty); }
            set { SetValue(TypeProperty, value); }
        }
 
        public string TypeName
        { 
            get 
            {
                string typeName = string.Empty; 
                this.ToolTip = null;
                if (null != this.Type)
                {
                    if (TypePresenter.DefaultTypes.Contains(this.Type)) 
                    {
                        typeName = this.Type.Name; 
                    } 
                    else
                    { 
                        typeName = TypeNameHelper.GetDisplayName(this.Type, true);
                    }
                    this.ToolTip = typeName;
                } 
                return typeName;
            } 
        } 

        AssemblyContextControlItem AssemblyContext 
        {
            get
            {
                return (null != Context ? Context.Items.GetValue() : null); 
            }
        } 
 
        string BrowseTypeString
        { 
            get { return (string)this.FindResource("BrowseTypeString"); }
        }

        string NullString 
        {
            get { return "(null)"; } 
        } 

        protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer() 
        {
            return new UIElementAutomationPeer(this);
        }
 
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        { 
            base.OnMouseLeftButtonDown(e); 
            this.isMouseLeftButtonDown = true;
            e.Handled = true; 
        }

        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        { 
            base.OnMouseLeftButtonUp(e);
            if (this.isMouseLeftButtonDown) 
            { 
                if (this.BrowseTypeDirectly)
                { 
                    HandleBrowseType();
                }
                else
                { 
                    this.EnableEdit();
                } 
            } 
            this.isMouseLeftButtonDown = false;
            e.Handled = true; 
        }

        protected override void OnPreviewKeyDown(KeyEventArgs e)
        { 
            base.OnPreviewKeyDown(e);
            if (IsPreviewKey(e.Key)) 
            { 
                Preview();
            } 
        }

        internal static bool IsPreviewKey(Key key)
        { 
            return (key == Key.F2 || key == Key.Space || key == Key.Enter);
        } 
 
        internal void Preview()
        { 
            if (this.BrowseTypeDirectly)
            {
                HandleBrowseType();
            } 
            else
            { 
                this.EnableEdit(); 
            }
        } 

        static void OnContextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            TypePresenter ctrl = (TypePresenter)sender; 
            ctrl.OnItemsChanged();
        } 
 
        static void OnAllowNullChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        { 
            TypePresenter ctrl = (TypePresenter)sender;
            ctrl.OnItemsChanged();
        }
 
        static void OnBrowseTypeDirectlyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        { 
            TypePresenter ctrl = (TypePresenter)sender; 
            if (!(bool)args.NewValue)
            { 
                ctrl.typeComboBox.Visibility = Visibility.Visible;
                ctrl.typeTextBlock.Visibility = Visibility.Collapsed;
                ctrl.Focusable = false;
            } 
            else
            { 
                ctrl.typeComboBox.Visibility = Visibility.Collapsed; 
                ctrl.typeTextBlock.Visibility = Visibility.Visible;
                ctrl.Focusable = true; 
            }
        }

        static void OnTypeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) 
        {
            TypePresenter ctrl = (TypePresenter)sender; 
            ctrl.lastSelection = (Type)args.NewValue; 

            if (null != ctrl.PropertyChanged) 
            {
                ctrl.PropertyChanged(ctrl, new PropertyChangedEventArgs("TypeName"));
            }
 
            if (null == ctrl.lastSelection)
            { 
                ctrl.typeComboBox.SelectedIndex = ctrl.typeComboBox.Items.IndexOf(ctrl.NullTypeWrapper); 
            }
 
            ctrl.Text = ctrl.TypeName;
            ctrl.RaiseEvent(new RoutedEventArgs(TypePresenter.TypeChangedEvent, ctrl));
        }
 
        static void OnFilterChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        { 
            TypePresenter ctrl = (TypePresenter)sender; 
            if (null != ctrl.PropertyChanged)
            { 
                ctrl.PropertyChanged(ctrl, new PropertyChangedEventArgs("Items"));
            }
        }
 
        static void OnMostRecentlyUsedTypesPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        { 
            TypePresenter ctrl = (TypePresenter)sender; 
            ((ObservableCollection)args.NewValue).CollectionChanged += ctrl.OnMostRecentlyUsedTypesChanged;
            ((ObservableCollection)args.OldValue).CollectionChanged -= ctrl.OnMostRecentlyUsedTypesChanged; 

            ctrl.OnItemsChanged();
        }
 
        static object OnCoerceMostRecentlyUsedTypes(DependencyObject sender, object value)
        { 
            if (value != null) 
            {
                return value; 
            }
            else
            {
                return TypePresenter.DefaultMostRecentlyUsedTypes; 
            }
        } 
 
        void DisableEdit()
        { 
            if (BrowseTypeDirectly)
            {
                this.typeTextBlock.Visibility = Visibility.Visible;
                this.typeComboBox.Visibility = Visibility.Collapsed; 
            }
        } 
 
        void EnableEdit()
        { 
            if (BrowseTypeDirectly)
            {
                this.typeTextBlock.Visibility = Visibility.Collapsed;
                this.typeComboBox.Visibility = Visibility.Visible; 
            }
            this.typeComboBox.Focus(); 
        } 

        // return true if KeyDownEvent should be set to handled 
        bool HandleBrowseType()
        {
            bool retval = false;
            TypeWrapper wrapper = (TypeWrapper)this.typeComboBox.SelectedItem; 

            if ((wrapper != null && !wrapper.IsTypeDefinition) 
                || this.BrowseTypeDirectly) 
            {
                Type result = null; 
                bool? dialogResult = true;
                bool typeIsArray = true;
                bool fireEvent = false;
                //handle choosing an array of T 
                if (wrapper != null && typeof(ArrayOf<>) == wrapper.Type)
                { 
                    fireEvent = true; 
                    this.RaiseEvent(new RoutedEventArgs(TypePresenter.TypeBrowserOpenedEvent, this));
                    result = wrapper.Type; 
                }
                else if (wrapper != null && wrapper.DisplayName == NullString)
                {
                    this.Type = null; 
                    return false;
                } 
                else 
                {
                    retval = true; 
                    fireEvent = true;
                    this.RaiseEvent(new RoutedEventArgs(TypePresenter.TypeBrowserOpenedEvent, this));
                    TypeBrowser browser = new TypeBrowser(AssemblyContext, this.Context, this.Filter);
                    SetWindowOwner(browser); 
                    if (this.CenterTypeBrowserDialog)
                    { 
                        browser.WindowStartupLocation = WindowStartupLocation.CenterScreen; 
                    }
                    dialogResult = browser.ShowDialog(); 
                    if (dialogResult.HasValue && dialogResult.Value)
                    {
                        result = browser.ConcreteType;
                    } 

                    typeIsArray = false; 
                } 

                if (dialogResult.HasValue && dialogResult.Value) 
                {
                    //user may have chosen generic type (IList)
                    if (result.IsGenericTypeDefinition)
                    { 
                        retval = true;
                        ActivityTypeResolver wnd = new ActivityTypeResolver(); 
                        SetWindowOwner(wnd); 
                        wnd.Context = this.Context;
                        wnd.EditedType = result; 
                        if (this.CenterActivityTypeResolverDialog)
                        {
                            wnd.WindowStartupLocation = WindowStartupLocation.CenterScreen;
                        } 

                        result = (true == wnd.ShowDialog() ? wnd.ConcreteType : null); 
                    } 
                    //if we have a type
                    if (null != result) 
                    {
                        //if we have a ArrayOf, create actual array type
                        if (typeIsArray)
                        { 
                            result = result.GetGenericArguments()[0].MakeArrayType();
                        } 
                        //add it to the cache 
                        if (!MostRecentlyUsedTypes.Any(p => Type.Equals(p, result)))
                        { 
                            MostRecentlyUsedTypes.Add(result);
                        }

                        //and return updated result 
                        this.Type = result;
                    } 
                    else 
                    {
                        this.Type = this.lastSelection; 
                    }

                    BindingExpression binding = this.typeComboBox.GetBindingExpression(ComboBox.SelectedItemProperty);
                    binding.UpdateTarget(); 
                }
                else 
                { 
                    SetComboBoxToLastSelection();
                } 
                if (fireEvent)
                {
                    this.RaiseEvent(new RoutedEventArgs(TypePresenter.TypeBrowserClosedEvent, this));
                } 
            }
 
            return retval; 
        }
 
        void OnMostRecentlyUsedTypesChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            OnItemsChanged();
        } 

        void OnItemsChanged() 
        { 
            if (null != PropertyChanged)
            { 
                PropertyChanged(this, new PropertyChangedEventArgs("Items"));
            }
        }
 
        void OnTypePresenterDropDownClosed(object sender, EventArgs e)
        { 
            HandleBrowseType(); 
            DisableEdit();
            if (!this.BrowseTypeDirectly) 
            {
                this.typeComboBox.Focus();
            }
            else 
            {
                this.Focus(); 
            } 
        }
 
        void OnTypePresenterKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            { 
                if (HandleBrowseType())
                { 
                    e.Handled = true; 
                }
                DisableEdit(); 

                FocusOnVisibleControl();
            }
        } 

        void OnTypePresenterLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) 
        { 
            if (!(e.NewFocus == this))
            { 
                if (!(this.typeComboBox.IsDropDownOpen || this.typeComboBox.IsSelectionBoxHighlighted))
                {
                    DisableEdit();
                } 
            }
        } 
 
        void SetWindowOwner(Window wnd)
        { 
            if (null != this.Context)
            {
                WindowHelperService service = this.Context.Services.GetService();
                if (null != service) 
                {
                    service.TrySetWindowOwner(this, wnd); 
                } 
            }
        } 

        // internal converter class - assign a meaningful AutomationProperties.Name to the type presenter
        // AutomationProperties.Name = Label + the string displayed on the TypePresenter
        sealed class AutomationNameConverter : IMultiValueConverter 
        {
            public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
            { 
                Fx.Assert(values.Length == 2, "There should be exactly 2 values");
                return (string)values[0] + ": " + (string)values[1]; 
            }

            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
            { 
                Fx.Assert("Not supported!");
                return null; 
            } 
        }
    } 

    [Fx.Tag.XamlVisible(false)]
    public sealed class TypeWrapper
    { 
        string displayName;
        bool isTypeDefinition; 
        Type type; 

        internal TypeWrapper(Type type) 
        {
            this.type = type;
            this.isTypeDefinition = true;
            this.Tag = DisplayName; 
        }
 
        internal TypeWrapper(string text, string tag, Type type) 
        {
            this.displayName = text; 
            this.isTypeDefinition = false;
            this.Tag = tag;
            this.type = type;
        } 

        public string DisplayName 
        { 
            get
            { 
                if (this.isTypeDefinition)
                {
                    if (TypePresenter.DefaultTypes.Contains(this.type))
                    { 
                        return this.type.Name;
                    } 
 
                    return TypeNameHelper.GetDisplayName(this.Type, true);
                } 
                return this.displayName;
            }
        }
 
        public bool IsTypeDefinition
        { 
            get { return this.isTypeDefinition; } 
        }
 
        public object Tag
        {
            get;
            private set; 
        }
 
        [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "By design.")] 
        public Type Type
        { 
            get { return this.type; }
        }

        public override string ToString() 
        {
            return Tag as string; 
        } 

        public override bool Equals(object obj) 
        {
            TypeWrapper that = obj as TypeWrapper;
            if (that == null)
            { 
                return false;
            } 
            if (that.IsTypeDefinition ^ this.IsTypeDefinition) 
            {
                return false; 
            }
            if (this.displayName != that.displayName)
            {
                return false; 
            }
            return object.Equals(this.Type, that.Type); 
        } 

        public override int GetHashCode() 
        {
            if (this.Type != null)
            {
                return this.Type.GetHashCode(); 
            }
            else 
            { 
                return base.GetHashCode();
            } 
        }
    }

    sealed class ArrayOf 
    {
    } 
 
    sealed class BrowseForType
    { 
    }

    // internal converter class - keeps link between display friendly string representation of types
    // and actual underlying system type. 
    sealed class TypeWrapperConverter : IValueConverter
    { 
        TypePresenter typePresenter; 

        //ctor - initialzied with list of loaded types into the presenter 
        internal TypeWrapperConverter(TypePresenter typePresenter)
        {
            this.typePresenter = typePresenter;
        } 

        //convert from System.Type to TypeWrapper (display friendly) 
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
        {
            if (null != value) 
            {
                //lookup in loaded types if type is already there

                //if no - add it to collection - may be reused later 
                if (null == this.typePresenter.MostRecentlyUsedTypes.SingleOrDefault(p => Type.Equals(p, (Type)value)))
                { 
                    this.typePresenter.MostRecentlyUsedTypes.Add((Type)value); 
                }
 
                return new TypeWrapper((Type)value);
            }
            else
            { 
                return this.typePresenter.NullTypeWrapper;
            } 
        } 

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
        {
            //convert back - just get the Type property of the wrapper object
            TypeWrapper typeWrapper = value as TypeWrapper;
 
            if (typeWrapper == this.typePresenter.NullTypeWrapper)
            { 
                return null; 
            }
 
            if (null != typeWrapper && null != typeWrapper.Type && typeof(ArrayOf<>) != typeWrapper.Type && typeof(BrowseForType) != typeWrapper.Type)
            {
                return typeWrapper.Type;
            } 

            return Binding.DoNothing; 
        } 
    }
} 

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