File: System.Activities.Presentation\System\Activities\Presentation\Base\Core\Internal\PropertyEditing\PropertyValueEditorCommandHandler.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.Collections.Generic;
    using System.Diagnostics;
    using System.Windows;
    using System.Windows.Input;
 
    using System.Activities.Presentation;
    using System.Runtime;
    using System.Activities.Presentation.Model;
    using System.Activities.Presentation.PropertyEditing;
 
    using System.Activities.Presentation.Internal.PropertyEditing.Model;
 
    // <summary>
    // Container for standard PropertyValueEditorCommand handlers.  These handlers need to do their
    // work both for the PropertyInspector control as well as for any standard WPF dialog editor
    // launched from the PropertyInspector itself.  As such, the functionality is extracted here
    // to be shared in both cases.
    // </summary>
    internal class PropertyValueEditorCommandHandler : IDisposable 
    {
 
        private UIElement _commandHost;
        private List<CommandBinding> _activeCommandBindings = new List<CommandBinding>();
        private List<ModelEditingScope> _pendingTransactions = new List<ModelEditingScope>();
 
        public PropertyValueEditorCommandHandler(UIElement commandHost) 
        {
            Fx.Assert(commandHost != null, "commandHost parameter is null");
            _commandHost = commandHost;
 
            AddEditModeCommandBindings();
            AddTransactionCommandBindings();
 
            foreach (CommandBinding binding in _activeCommandBindings)
            {
                _commandHost.CommandBindings.Add(binding);
            }
        }
 
        // <summary>
        // Cleans up by removing all CommandBindings added by this class from the commandHost
        // </summary>
        public void Dispose() 
        {
            if (_commandHost != null && _activeCommandBindings.Count > 0) 
            {
                foreach (CommandBinding binding in _activeCommandBindings) 
                {
                    _commandHost.CommandBindings.Remove(binding);
                }
                _activeCommandBindings.Clear();
            }
        }
 
        // <summary>
        // Commits any pending and open transactions in the correct order
        // </summary>
        public void CommitOpenTransactions() 
        {
            for (int i = _pendingTransactions.Count - 1; i >= 0; i--) 
            {
                _pendingTransactions[i].Complete();
                _pendingTransactions.RemoveAt(i);
            }
        }
 
        // <summary>
        // Aborts any pending and open transactions in the correct order
        // </summary>
        public void AbortOpenTransactions() 
        {
            for (int i = _pendingTransactions.Count - 1; i >= 0; i--) 
            {
                _pendingTransactions[i].Revert();
                _pendingTransactions.RemoveAt(i);
            }
        }
 
        // ActiveEditMode Switch Handlers
 
        // Adds handlers for ShowInlineEditor, ShowExtendedPopupEditor, ShowExtendedPinnedEditor,
        // and ShowDialogEditor commands.  These handlers the ActiveEditMode of the closest PropertyContainer
        // that contains the UIElement that invoked it
        private void AddEditModeCommandBindings() 
        {
            _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.ShowInlineEditor, OnShowInlineEditor));
            _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.ShowExtendedPopupEditor, OnShowExtendedPopupEditor));
            _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.ShowExtendedPinnedEditor, OnShowExtendedPinnedEditor));
            _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.ShowDialogEditor, OnShowDialogEditor));
        }
 
        private void OnShowInlineEditor(object sender, ExecutedRoutedEventArgs e) 
        {
            SwitchActiveEditMode(e, PropertyContainerEditMode.Inline);
        }
 
        private void OnShowExtendedPopupEditor(object sender, ExecutedRoutedEventArgs e) 
        {
            SwitchActiveEditMode(e, PropertyContainerEditMode.ExtendedPopup);
        }
 
        private void OnShowExtendedPinnedEditor(object sender, ExecutedRoutedEventArgs e) 
        {
            SwitchActiveEditMode(e, PropertyContainerEditMode.ExtendedPinned);
        }
 
        private void OnShowDialogEditor(object sender, ExecutedRoutedEventArgs e) 
        {
            SwitchActiveEditMode(e, PropertyContainerEditMode.Dialog);
        }
 
        private static void SwitchActiveEditMode(ExecutedRoutedEventArgs e, PropertyContainerEditMode newMode) 
        {
            PropertyContainer container = GetContainerFromEventArgs(e);
            if (container == null)
            {
                return;
            }
 
            container.ActiveEditMode = newMode;
        }
 
 
 
        // Transaction Handlers
 
        // Adds command handlers for BeginTransaction, CommitTransaction, and AbortTransaction
        // commands.  These handlers open, commit, or abort a transaction
        private void AddTransactionCommandBindings() 
        {
            _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.BeginTransaction, OnBeginTransaction));
            _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.CommitTransaction, OnCommitTransaction));
            _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.AbortTransaction, OnAbortTransaction));
        }
 
        private void OnBeginTransaction(object sender, ExecutedRoutedEventArgs e) 
        {
            ModelPropertyEntryBase property = GetContainedPropertyFromEventArgs(e);
            if (property == null)
            {
                return;
            }
 
            _pendingTransactions.Add(property.BeginEdit(e.Parameter as string));
        }
 
        private void OnCommitTransaction(object sender, ExecutedRoutedEventArgs e) 
        {
            if (_pendingTransactions.Count == 0)
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(System.Activities.Presentation.Internal.Properties.Resources.PropertyEditing_ErrorCommit_NoTransactionsOpened));
            }
 
            try 
            {
                _pendingTransactions[_pendingTransactions.Count - 1].Complete();
            }
            finally 
            {
                _pendingTransactions.RemoveAt(_pendingTransactions.Count - 1);
            }
        }
 
        private void OnAbortTransaction(object sender, ExecutedRoutedEventArgs e) 
        {
            if (_pendingTransactions.Count == 0)
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(System.Activities.Presentation.Internal.Properties.Resources.PropertyEditing_ErrorAbort_NoTransactionsOpened));
            }
 
            try 
            {
                _pendingTransactions[_pendingTransactions.Count - 1].Revert();
            }
            finally 
            {
                _pendingTransactions.RemoveAt(_pendingTransactions.Count - 1);
            }
        }
 
 
 
        // Static Helpers
 
        private static ModelPropertyEntryBase GetContainedPropertyFromEventArgs(ExecutedRoutedEventArgs e) 
        {
            PropertyContainer container = GetContainerFromEventArgs(e);
            if (container == null)
            {
                return null;
            }
 
            return container.PropertyEntry as ModelPropertyEntryBase;
        }
 
        private static PropertyContainer GetContainerFromEventArgs(ExecutedRoutedEventArgs e) 
        {
            DependencyObject source = e.OriginalSource as DependencyObject;
            if (source == null)
            {
                return null;
            }
 
            return PropertyContainer.GetOwningPropertyContainer(source);
        }
 
 
    }
}