1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //----------------------------------------------------------------
4 namespace System.Activities.Presentation.Internal.PropertyEditing
7 using System.Collections.Generic;
8 using System.Diagnostics;
10 using System.Windows.Input;
12 using System.Activities.Presentation;
14 using System.Activities.Presentation.Model;
15 using System.Activities.Presentation.PropertyEditing;
17 using System.Activities.Presentation.Internal.PropertyEditing.Model;
20 // Container for standard PropertyValueEditorCommand handlers. These handlers need to do their
21 // work both for the PropertyInspector control as well as for any standard WPF dialog editor
22 // launched from the PropertyInspector itself. As such, the functionality is extracted here
23 // to be shared in both cases.
25 internal class PropertyValueEditorCommandHandler : IDisposable
28 private UIElement _commandHost;
29 private List<CommandBinding> _activeCommandBindings = new List<CommandBinding>();
30 private List<ModelEditingScope> _pendingTransactions = new List<ModelEditingScope>();
32 public PropertyValueEditorCommandHandler(UIElement commandHost)
34 Fx.Assert(commandHost != null, "commandHost parameter is null");
35 _commandHost = commandHost;
37 AddEditModeCommandBindings();
38 AddTransactionCommandBindings();
40 foreach (CommandBinding binding in _activeCommandBindings)
42 _commandHost.CommandBindings.Add(binding);
47 // Cleans up by removing all CommandBindings added by this class from the commandHost
51 if (_commandHost != null && _activeCommandBindings.Count > 0)
53 foreach (CommandBinding binding in _activeCommandBindings)
55 _commandHost.CommandBindings.Remove(binding);
57 _activeCommandBindings.Clear();
62 // Commits any pending and open transactions in the correct order
64 public void CommitOpenTransactions()
66 for (int i = _pendingTransactions.Count - 1; i >= 0; i--)
68 _pendingTransactions[i].Complete();
69 _pendingTransactions.RemoveAt(i);
74 // Aborts any pending and open transactions in the correct order
76 public void AbortOpenTransactions()
78 for (int i = _pendingTransactions.Count - 1; i >= 0; i--)
80 _pendingTransactions[i].Revert();
81 _pendingTransactions.RemoveAt(i);
85 // ActiveEditMode Switch Handlers
87 // Adds handlers for ShowInlineEditor, ShowExtendedPopupEditor, ShowExtendedPinnedEditor,
88 // and ShowDialogEditor commands. These handlers the ActiveEditMode of the closest PropertyContainer
89 // that contains the UIElement that invoked it
90 private void AddEditModeCommandBindings()
92 _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.ShowInlineEditor, OnShowInlineEditor));
93 _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.ShowExtendedPopupEditor, OnShowExtendedPopupEditor));
94 _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.ShowExtendedPinnedEditor, OnShowExtendedPinnedEditor));
95 _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.ShowDialogEditor, OnShowDialogEditor));
98 private void OnShowInlineEditor(object sender, ExecutedRoutedEventArgs e)
100 SwitchActiveEditMode(e, PropertyContainerEditMode.Inline);
103 private void OnShowExtendedPopupEditor(object sender, ExecutedRoutedEventArgs e)
105 SwitchActiveEditMode(e, PropertyContainerEditMode.ExtendedPopup);
108 private void OnShowExtendedPinnedEditor(object sender, ExecutedRoutedEventArgs e)
110 SwitchActiveEditMode(e, PropertyContainerEditMode.ExtendedPinned);
113 private void OnShowDialogEditor(object sender, ExecutedRoutedEventArgs e)
115 SwitchActiveEditMode(e, PropertyContainerEditMode.Dialog);
118 private static void SwitchActiveEditMode(ExecutedRoutedEventArgs e, PropertyContainerEditMode newMode)
120 PropertyContainer container = GetContainerFromEventArgs(e);
121 if (container == null)
126 container.ActiveEditMode = newMode;
131 // Transaction Handlers
133 // Adds command handlers for BeginTransaction, CommitTransaction, and AbortTransaction
134 // commands. These handlers open, commit, or abort a transaction
135 private void AddTransactionCommandBindings()
137 _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.BeginTransaction, OnBeginTransaction));
138 _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.CommitTransaction, OnCommitTransaction));
139 _activeCommandBindings.Add(new CommandBinding(PropertyValueEditorCommands.AbortTransaction, OnAbortTransaction));
142 private void OnBeginTransaction(object sender, ExecutedRoutedEventArgs e)
144 ModelPropertyEntryBase property = GetContainedPropertyFromEventArgs(e);
145 if (property == null)
150 _pendingTransactions.Add(property.BeginEdit(e.Parameter as string));
153 private void OnCommitTransaction(object sender, ExecutedRoutedEventArgs e)
155 if (_pendingTransactions.Count == 0)
157 throw FxTrace.Exception.AsError(new InvalidOperationException(System.Activities.Presentation.Internal.Properties.Resources.PropertyEditing_ErrorCommit_NoTransactionsOpened));
162 _pendingTransactions[_pendingTransactions.Count - 1].Complete();
166 _pendingTransactions.RemoveAt(_pendingTransactions.Count - 1);
170 private void OnAbortTransaction(object sender, ExecutedRoutedEventArgs e)
172 if (_pendingTransactions.Count == 0)
174 throw FxTrace.Exception.AsError(new InvalidOperationException(System.Activities.Presentation.Internal.Properties.Resources.PropertyEditing_ErrorAbort_NoTransactionsOpened));
179 _pendingTransactions[_pendingTransactions.Count - 1].Revert();
183 _pendingTransactions.RemoveAt(_pendingTransactions.Count - 1);
191 private static ModelPropertyEntryBase GetContainedPropertyFromEventArgs(ExecutedRoutedEventArgs e)
193 PropertyContainer container = GetContainerFromEventArgs(e);
194 if (container == null)
199 return container.PropertyEntry as ModelPropertyEntryBase;
202 private static PropertyContainer GetContainerFromEventArgs(ExecutedRoutedEventArgs e)
204 DependencyObject source = e.OriginalSource as DependencyObject;
210 return PropertyContainer.GetOwningPropertyContainer(source);