File: System.Activities.Presentation\System\Activities\Presentation\Base\Core\Internal\PropertyEditing\PropertyToolBar.cs
Project: ndp\cdf\src\NetFx40\Tools\System.Activities.Presentation.csproj (System.Activities.Presentation)
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Presentation.Internal.PropertyEditing 
{
    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Windows;
    using System.Windows.Automation.Peers;
    using System.Windows.Controls;
    using System.Runtime;
 
    using System.Activities.Presentation.Internal.PropertyEditing.Automation;
    using System.Activities.Presentation.Internal.PropertyEditing.State;
    using System.Activities.Presentation.Internal.PropertyEditing.Views;
 
    // <summary>
    // Container control that hosts both the property-search UI as well as the view-switching UI
    // </summary>
    internal sealed class PropertyToolBar : Control, INotifyPropertyChanged 
    {
 
        // <summary>
        // Property representing the currently-selected IPropertyViewManager
        // </summary>
        public static DependencyProperty CurrentViewManagerProperty = DependencyProperty.Register(
            "CurrentViewManager",
            typeof(IPropertyViewManager),
            typeof(PropertyToolBar),
            new PropertyMetadata(null, OnCurrentViewManagerChanged));
 
        // <summary>
        // Property containing a link to the CategoryList control instance that this
        // PropertyToolBar controls.  We need this link to be able to change the appearance
        // of each new generated CategoryContainer (whether it should show a header or not).
        // That way CategoryList doesn't need to know anything about this class.
        // </summary>
        public static DependencyProperty CategoryListProperty = DependencyProperty.Register(
            "CategoryList",
            typeof(CategoryList),
            typeof(PropertyToolBar),
            new PropertyMetadata(null, OnCategoryListChanged));
 
        private string _persistenceId;
        private bool _persistViewManagerChanges = true;
 
        public PropertyToolBar() 
        {
            this.Loaded += new RoutedEventHandler(OnLoaded);
            this.Unloaded += new RoutedEventHandler(OnUnloaded);
        }
 
        // <summary>
        // Event we fire when the CurrentViewManager changes
        // </summary>
        public event EventHandler CurrentViewManagerChanged;
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        // <summary>
        // Gets or set the currently selected IPropertyViewManager
        // </summary>
        public IPropertyViewManager CurrentViewManager 
        {
            get { return (IPropertyViewManager)this.GetValue(CurrentViewManagerProperty); }
            set { this.SetValue(CurrentViewManagerProperty, value); }
        }
 
        // <summary>
        // Gets or set the value of the CategoryListProperty
        // </summary>
        public CategoryList CategoryList 
        {
            get { return (CategoryList)this.GetValue(CategoryListProperty); }
            set { this.SetValue(CategoryListProperty, value); }
        }
 
        // <summary>
        // Gets or sets a string ID that we use to differentiate between the states of different
        // PropertyToolBar instances.  Currently, we only care about two different PropertyToolBar
        // buckets - (1) the PTBs we use in the main PI and (2) the PTBs we use in collection editors.
        // </summary>
        public string PersistenceId 
        {
            get {
                return _persistenceId;
            }
            set {
                if (_persistenceId != value) 
                {
                    _persistenceId = value;
 
                    if (this.CurrentViewManager == null) 
                    {
                        bool oldPersistViewManagerChanges = _persistViewManagerChanges;
                        try 
                        {
                            _persistViewManagerChanges = false;
                            this.CurrentViewManager = PropertyViewManagerStateContainer.Instance.GetPropertyViewManager(_persistenceId);
                        }
                        finally 
                        {
                            _persistViewManagerChanges = oldPersistViewManagerChanges;
                        }
                    }
 
                    OnPropertyChanged("PersistenceId");
                }
            }
        }
 
        // <summary>
        // Convenience accessor for the UI data binding
        // </summary>
        public bool IsCategoryViewSelected 
        {
            get {
                if (this.CurrentViewManager != null)
                {
                    return this.CurrentViewManager == ByCategoryViewManager.Instance;
                }
 
                return false;
            }
            set {
                // No need to fire PropertyChanged events here - changing CurrentViewManager
                // will fire those events as a side-effect
                //
                if (this.CurrentViewManager == ByCategoryViewManager.Instance ^ value) 
                {
                    if (value)
                    {
                        this.CurrentViewManager = ByCategoryViewManager.Instance;
                    }
                    else
                    {
                        this.CurrentViewManager = AlphabeticalViewManager.Instance;
                    }
                }
            }
        }
 
        // <summary>
        // Convenience accessor for the UI data binding
        // </summary>
        public bool IsAlphaViewSelected 
        {
            get {
                if (this.CurrentViewManager != null)
                {
                    return this.CurrentViewManager == AlphabeticalViewManager.Instance;
                }
 
                return false;
            }
            set {
                // No need to fire PropertyChanged events here - changing CurrentViewManager
                // will fire those events as a side-effect
                //
                if (this.CurrentViewManager == AlphabeticalViewManager.Instance ^ value) 
                {
                    if (value)
                    {
                        this.CurrentViewManager = AlphabeticalViewManager.Instance;
                    }
                    else
                    {
                        this.CurrentViewManager = ByCategoryViewManager.Instance;
                    }
                }
            }
        }
 
        // AutomationPeer Stuff
 
        internal RadioButton ByCategoryViewButton 
        { get { return VisualTreeUtils.GetNamedChild<RadioButton>(this, "PART_ByCategoryViewButton"); } }
        internal RadioButton AlphaViewButton 
        { get { return VisualTreeUtils.GetNamedChild<RadioButton>(this, "PART_AlphaViewButton"); } }
        internal TextBlock SearchLabel 
        { get { return VisualTreeUtils.GetNamedChild<TextBlock>(this, "PART_SearchLabel"); } }
        internal TextBox SearchTextBox 
        { get { return VisualTreeUtils.GetNamedChild<TextBox>(this, "PART_SearchTextBox"); } }
        internal Button SearchClearButton 
        { get { return VisualTreeUtils.GetNamedChild<Button>(this, "PART_SearchClearButton"); } }
 
        private void OnLoaded(object sender, RoutedEventArgs e) 
        {
            PropertyViewManagerStateContainer.Instance.ContentRestored += new EventHandler(OnGlobalPropertyViewManagerRestored);
        }
 
        private void OnUnloaded(object sender, RoutedEventArgs e) 
        {
            PropertyViewManagerStateContainer.Instance.ContentRestored -= new EventHandler(OnGlobalPropertyViewManagerRestored);
        }
 
        private void OnGlobalPropertyViewManagerRestored(object sender, EventArgs e) 
        {
 
            // If the state of PropertyViewManagerStateContainer has been restored
            // update the current view of the PropertyToolBar based on the restored state
 
            if (this.PersistenceId != null) 
            {
                bool oldPersistViewManagerChanges = _persistViewManagerChanges;
                try 
                {
                    _persistViewManagerChanges = false;
                    this.CurrentViewManager = PropertyViewManagerStateContainer.Instance.GetPropertyViewManager(this.PersistenceId);
                }
                finally 
                {
                    _persistViewManagerChanges = oldPersistViewManagerChanges;
                }
            }
        }
 
        // CurrentViewManager DP
 
        private static void OnCurrentViewManagerChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
        {
            PropertyToolBar theThis = obj as PropertyToolBar;
            if (theThis == null) 
            {
                return;
            }
 
            theThis.OnPropertyChanged("IsCategoryViewSelected");
            theThis.OnPropertyChanged("IsAlphaViewSelected");
 
            // Store and persist the CurrentViewManager value only if:
            // 
            // * this change did not come from PropertyViewManagerStateContainer itself
            // * we have a persistence ID to differentiate this control instance by
            // * this is not the first time the value was set - in other words, only
            //   store values that were triggered by the user making a conscious change
            //
            if (theThis.PersistenceId != null && theThis._persistViewManagerChanges && e.OldValue != null)
            {
                PropertyViewManagerStateContainer.Instance.StorePropertyViewManager(theThis.PersistenceId, e.NewValue as IPropertyViewManager);
            }
 
            // fire this event after we have stored the propertyviewmanager, so that the StateChanged event will get
            // the updated view-manager
            if (theThis.CurrentViewManagerChanged != null)
            {
                theThis.CurrentViewManagerChanged(theThis, EventArgs.Empty);
            }
 
            //refresh filter 
            if (null != theThis.CategoryList)
            {
                theThis.CategoryList.RefreshFilter();
            }
 
        }
 
 
 
        // CategoryList DP
 
        private static void OnCategoryListChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
        {
            PropertyToolBar theThis = obj as PropertyToolBar;
            if (theThis == null) 
            {
                return;
            }
 
            if (e.OldValue != null)
            {
                theThis.UnhookEvents(e.OldValue as CategoryList);
            }
 
            if (e.NewValue != null)
            {
                theThis.HookEvents(e.NewValue as CategoryList);
            }
        }
 
        private void HookEvents(CategoryList categoryList) 
        {
            if (categoryList == null) 
            {
                Debug.Fail("This method shouldn't be called when there is no CategoryList instance to process.");
                return;
            }
 
            categoryList.ContainerGenerated += new ContainerGeneratedHandler(OnCategoryContainerGenerated);
        }
 
        private void UnhookEvents(CategoryList categoryList) 
        {
            if (categoryList == null) 
            {
                Debug.Fail("This method shouldn't be called when there is no CategoryList instance to process.");
                return;
            }
 
            categoryList.ContainerGenerated -= new ContainerGeneratedHandler(OnCategoryContainerGenerated);
        }
 
        private void OnCategoryContainerGenerated(object sender, ContainerGeneratedEventArgs e) 
        {
            if (e.Container == null) 
            {
                return;
            }
            e.Container.ShowCategoryHeader = this.CurrentViewManager == null ? true : this.CurrentViewManager.ShowCategoryHeaders;
        }
 
 
 
        protected override AutomationPeer OnCreateAutomationPeer() 
        {
            return new UIElementAutomationPeer(this);
        }
 
 
 
        // INotifyPropertyChanged Members
 
        private void OnPropertyChanged(string propertyName) 
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
 
 
    }
}