[bcl] Updates referencesource to 4.7.1
[mono-project.git] / mcs / class / referencesource / System.Activities.Core.Presentation / System / Activities / Core / Presentation / TryCatchDesigner.xaml.cs
blobf602c593a594fe01a9d217cbf6c9b258a4bf8614
1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //----------------------------------------------------------------
5 namespace System.Activities.Core.Presentation
7 using System.Activities.Presentation;
8 using System.Activities.Presentation.Metadata;
9 using System.Activities.Presentation.Model;
10 using System.Activities.Presentation.View;
11 using System.Activities.Presentation.Services;
12 using System.Activities.Statements;
13 using System.Collections.ObjectModel;
14 using System.Collections.Specialized;
15 using System.ComponentModel;
16 using System.Diagnostics.CodeAnalysis;
17 using System.IO;
18 using System.Runtime;
19 using System.Windows;
20 using System.Windows.Automation;
21 using System.Windows.Automation.Peers;
22 using System.Windows.Input;
23 using System.Windows.Threading;
24 using System.Windows.Controls;
25 using System.Activities.Presentation.View.OutlineView;
27 /// <summary>
28 /// Interaction logic for TryCatchDesigner.xaml
29 /// </summary>
30 partial class TryCatchDesigner
32 const string CatchesPropertyName = "Catches";
33 const string ExceptionTypePropertyName = "ExceptionType";
34 const string ExpandViewStateKey = "IsExpanded";
36 public static readonly DependencyProperty ShowTryExpandedProperty =
37 DependencyProperty.Register(
38 "ShowTryExpanded",
39 typeof(bool),
40 typeof(TryCatchDesigner),
41 new UIPropertyMetadata(true)
44 public static readonly DependencyProperty ShowFinallyExpandedProperty =
45 DependencyProperty.Register(
46 "ShowFinallyExpanded",
47 typeof(bool),
48 typeof(TryCatchDesigner),
49 new UIPropertyMetadata(false)
52 public static readonly DependencyProperty ShowTypePresenterExpandedProperty =
53 DependencyProperty.Register(
54 "ShowTypePresenterExpanded",
55 typeof(bool),
56 typeof(TryCatchDesigner),
57 new UIPropertyMetadata(false)
60 public static readonly DependencyProperty SelectedCatchProperty =
61 DependencyProperty.Register(
62 "SelectedCatch",
63 typeof(ModelItem),
64 typeof(TryCatchDesigner),
65 new UIPropertyMetadata(null));
67 static ObservableCollection<Type> mostRecentlyUsedTypes;
68 static ObservableCollection<Type> MostRecentlyUsedTypes
70 get
72 if (mostRecentlyUsedTypes == null)
74 mostRecentlyUsedTypes = new ObservableCollection<Type>
76 typeof(ArgumentException),
77 typeof(NullReferenceException),
78 typeof(IOException),
79 typeof(InvalidOperationException),
80 typeof(Exception),
83 return mostRecentlyUsedTypes;
87 public bool ShowTryExpanded
89 get
91 return (bool)this.GetValue(ShowTryExpandedProperty);
93 set
95 this.SetValue(ShowTryExpandedProperty, value);
99 public bool ShowFinallyExpanded
103 return (bool)this.GetValue(ShowFinallyExpandedProperty);
107 this.SetValue(ShowFinallyExpandedProperty, value);
111 public bool ShowTypePresenterExpanded
115 return (bool)this.GetValue(ShowTypePresenterExpandedProperty);
119 this.SetValue(ShowTypePresenterExpandedProperty, value);
123 ModelItem SelectedCatch
127 return (ModelItem)this.GetValue(SelectedCatchProperty);
131 this.SetValue(SelectedCatchProperty, value);
135 TypePresenter typePresenter;
136 Label addCatchHintLabel;
138 internal static void RegisterMetadata(AttributeTableBuilder builder)
140 Type type = typeof(TryCatch);
141 builder.AddCustomAttributes(type, new DesignerAttribute(typeof(TryCatchDesigner)));
142 builder.AddCustomAttributes(type, type.GetProperty("Try"), BrowsableAttribute.No);
143 builder.AddCustomAttributes(type, type.GetProperty("Finally"), BrowsableAttribute.No);
144 builder.AddCustomAttributes(type, type.GetProperty("Catches"), BrowsableAttribute.No);
145 builder.AddCustomAttributes(type, type.GetProperty("Variables"), BrowsableAttribute.No);
147 // Make Catches collection's node visible in the document treeview but hide Catches node itself.
148 builder.AddCustomAttributes(type, type.GetProperty("Catches"), new ShowPropertyInOutlineViewAttribute() { CurrentPropertyVisible = false });
151 [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
152 public TryCatchDesigner()
154 InitializeComponent();
156 this.Loaded += OnLoaded;
157 this.Unloaded += OnUnloaded;
160 void OnLoaded(object sender, RoutedEventArgs e)
162 this.Context.Items.Subscribe<Selection>(OnSelectionChanged);
163 // at this time, this.ModelItem is already set
164 this.ModelItem.PropertyChanged += OnModelItemPropertyChanged;
165 this.ModelItem.Properties[CatchesPropertyName].Collection.CollectionChanged += OnModelItemCollectionChanged;
167 ViewStateService viewStateService = this.Context.Services.GetService<ViewStateService>();
169 foreach (ModelItem modelItem in this.ModelItem.Properties["Catches"].Collection)
171 bool? isExpanded = (bool?)viewStateService.RetrieveViewState(modelItem, ExpandViewStateKey);
172 if (isExpanded != null && isExpanded.Value)
174 this.SelectedCatch = modelItem;
175 CollapseTryView();
176 CollapseFinallyView();
177 break;
182 void OnUnloaded(object sender, RoutedEventArgs e)
184 this.ModelItem.PropertyChanged -= OnModelItemPropertyChanged;
185 this.ModelItem.Properties[CatchesPropertyName].Collection.CollectionChanged -= OnModelItemCollectionChanged;
186 this.Context.Items.Unsubscribe<Selection>(OnSelectionChanged);
189 void OnModelItemPropertyChanged(object sender, PropertyChangedEventArgs e)
191 switch (e.PropertyName)
193 case "Try":
194 ExpandTryView();
195 break;
197 case "Finally":
198 ExpandFinallyView();
199 break;
201 default:
202 break;
206 void OnModelItemCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
208 // to update the filter
209 this.typePresenter.Filter = this.ExceptionTypeFilter;
212 void OnSelectionChanged(Selection selection)
214 if (IsDescendantOfTry(selection.PrimarySelection))
216 this.ExpandTryView();
218 else if (IsDescendantOfFinally(selection.PrimarySelection))
220 this.ExpandFinallyView();
222 else
224 foreach (ModelItem catchObject in this.ModelItem.Properties["Catches"].Collection)
226 if (IsDescendantOfCatch(catchObject, selection.PrimarySelection))
228 UpdateSelection(catchObject);
229 break;
235 bool IsDescendantOfTry(ModelItem descendant)
237 return IsDescendantOf(descendant, "Try");
240 bool IsDescendantOfFinally(ModelItem descendant)
242 return IsDescendantOf(descendant, "Finally");
245 static bool IsAncestorOf(ModelItem ancester, ModelItem descendant)
247 if (ancester == null)
249 return false;
252 ModelItem itr = descendant;
253 while (itr != null)
255 if (itr == ancester)
257 return true;
259 itr = itr.Parent;
261 return false;
264 bool IsDescendantOf(ModelItem descendant, string property)
266 if (descendant == null)
268 return false;
270 else
272 ModelItem propertyValue = this.ModelItem.Properties[property].Value;
273 return IsAncestorOf(propertyValue, descendant);
277 internal static bool IsDescendantOfCatch(ModelItem catchObject, ModelItem descendant)
279 Fx.Assert(catchObject != null, "Catch object mustn't be null.");
280 if (catchObject == descendant)
282 return true;
284 else
286 ModelItem activityAction = catchObject.Properties["Action"].Value;
287 if (activityAction != null)
289 ModelItem activityActionHandler = activityAction.Properties["Handler"].Value;
290 if (activityActionHandler != null)
292 return IsAncestorOf(activityActionHandler, descendant);
295 return false;
299 void UpdateSelection(ModelItem newSelectedCatch)
301 ModelItem oldSelectedCatch = this.SelectedCatch;
302 this.SelectedCatch = newSelectedCatch;
304 this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
306 if (oldSelectedCatch != null)
308 CatchDesigner oldSelectedCatchDesigner = (CatchDesigner)oldSelectedCatch.View;
309 if (oldSelectedCatchDesigner != null)
311 oldSelectedCatchDesigner.ExpandState = false;
312 oldSelectedCatchDesigner.PinState = false;
315 if (newSelectedCatch != null)
317 CollapseTryView();
318 CollapseFinallyView();
319 CatchDesigner newSelectedCatchDesigner = (CatchDesigner)newSelectedCatch.View;
320 if (newSelectedCatchDesigner != null)
322 newSelectedCatchDesigner.ExpandState = true;
323 newSelectedCatchDesigner.PinState = true;
326 }));
329 void CreateCatch(Type exceptionType)
331 if (exceptionType != null)
333 Type catchType = typeof(Catch<>).MakeGenericType(exceptionType);
334 object catchObject = Activator.CreateInstance(catchType);
336 Type activityActionType = typeof(ActivityAction<>).MakeGenericType(exceptionType);
337 object activityAction = Activator.CreateInstance(activityActionType);
339 Type argumentType = typeof(DelegateInArgument<>).MakeGenericType(exceptionType);
340 object exceptionArgument = Activator.CreateInstance(argumentType);
341 DelegateInArgument delegateArgument = exceptionArgument as DelegateInArgument;
342 Fx.Assert(null != delegateArgument, "delegate argument must be of DelegateInArgument type!");
343 delegateArgument.Name = "exception";
345 catchType.GetProperty(PropertyNames.Action).SetValue(catchObject, activityAction, null);
346 activityActionType.GetProperty(PropertyNames.ActionArgument).SetValue(activityAction, exceptionArgument, null);
348 this.ModelItem.Properties["Catches"].Collection.Add(catchObject);
352 void OnFinallyViewMouseDown(object sender, MouseButtonEventArgs e)
354 if (e.LeftButton == MouseButtonState.Pressed && e.ClickCount == 2)
356 SwitchTryCatchDesignerHelper.MakeRootDesigner(this);
357 e.Handled = true;
359 else if (e.LeftButton == MouseButtonState.Pressed)
361 ExpandFinallyView();
362 Keyboard.Focus((IInputElement)sender);
364 else if (e.RightButton == MouseButtonState.Pressed)
366 if (this.IsExpanded(this.ShowFinallyExpanded))
368 Keyboard.Focus((IInputElement)sender);
370 e.Handled = true;
374 void OnFinallyViewMouseUp(object sender, MouseButtonEventArgs e)
376 // avoid context menu upon right-click when it's collapsed
377 if (!IsExpanded(this.ShowFinallyExpanded) && e.RightButton == MouseButtonState.Released)
379 e.Handled = true;
383 bool IsExpanded(bool isExpanded)
385 DesignerView designerView = this.Context.Services.GetService<DesignerView>();
386 return isExpanded || designerView.ShouldExpandAll;
389 void OnTryViewMouseDown(object sender, MouseButtonEventArgs e)
391 if (e.LeftButton == MouseButtonState.Pressed && e.ClickCount == 2)
393 SwitchTryCatchDesignerHelper.MakeRootDesigner(this);
394 e.Handled = true;
396 else if (e.LeftButton == MouseButtonState.Pressed)
398 ExpandTryView();
399 Keyboard.Focus((IInputElement)sender);
401 else if (e.RightButton == MouseButtonState.Pressed)
403 if (this.IsExpanded(this.ShowTryExpanded))
405 Keyboard.Focus((IInputElement)sender);
407 e.Handled = true;
411 void OnTryViewMouseUp(object sender, MouseButtonEventArgs e)
413 // avoid context menu upon right-click when it's collapsed
414 if (!IsExpanded(this.ShowTryExpanded) && e.RightButton == MouseButtonState.Released)
416 e.Handled = true;
420 void ExpandFinallyView()
422 UpdateSelection(null);
423 this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
425 this.ShowTryExpanded = false;
426 this.ShowFinallyExpanded = true;
427 }));
430 void ExpandTryView()
432 UpdateSelection(null);
433 this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
435 this.ShowFinallyExpanded = false;
436 this.ShowTryExpanded = true;
437 }));
440 void CollapseFinallyView()
442 this.ShowFinallyExpanded = false;
445 void CollapseTryView()
447 this.ShowTryExpanded = false;
450 void OnTryViewKeyDown(object sender, KeyEventArgs e)
452 if (sender == e.OriginalSource && (e.Key == Key.Space || e.Key == Key.Enter))
454 ExpandTryView();
455 e.Handled = true;
459 void OnTryAddActivityKeyDown(object sender, KeyEventArgs e)
461 if (!LocalAppContextSwitches.UseLegacyAccessibilityFeatures)
463 if (sender == e.OriginalSource && (e.Key == Key.Space || e.Key == Key.Enter))
465 ExpandTryView();
466 e.Handled = true;
471 void OnFinallyViewKeyDown(object sender, KeyEventArgs e)
473 if (sender == e.OriginalSource && (e.Key == Key.Space || e.Key == Key.Enter))
475 ExpandFinallyView();
476 e.Handled = true;
480 void OnFinallyAddActivityKeyDown(object sender, KeyEventArgs e)
482 if (!LocalAppContextSwitches.UseLegacyAccessibilityFeatures)
484 if (sender == e.OriginalSource && (e.Key == Key.Space || e.Key == Key.Enter))
486 ExpandFinallyView();
487 e.Handled = true;
492 #region AddCatch Label & TypePresenter
494 void OnAddCatchMouseDown(object sender, MouseButtonEventArgs e)
496 if (e.LeftButton == MouseButtonState.Pressed)
498 this.SwitchToChooseException();
499 e.Handled = true;
503 void OnAddCatchGotFocus(object sender, RoutedEventArgs e)
505 this.SwitchToChooseException();
506 e.Handled = true;
509 void SwitchToChooseException()
511 this.ShowTypePresenterExpanded = true;
512 this.typePresenter.FocusOnVisibleControl();
515 void SwitchToHintText()
517 this.typePresenter.Type = null;
518 this.ShowTypePresenterExpanded = false;
519 Keyboard.Focus((IInputElement)this);
522 void OnAddCatchHintLabelLoaded(object sender, RoutedEventArgs e)
524 this.addCatchHintLabel = (Label)sender;
527 void OnAddCatchHintLabelUnloaded(object sender, RoutedEventArgs e)
529 this.addCatchHintLabel = null;
532 void OnTypePresenterLoaded(object sender, RoutedEventArgs e)
534 TypePresenter tp = (TypePresenter)sender;
535 Fx.Assert(tp != null, "sender must be a TypePresenter.");
537 this.typePresenter = tp;
538 this.typePresenter.Filter = this.ExceptionTypeFilter;
539 this.typePresenter.MostRecentlyUsedTypes = MostRecentlyUsedTypes;
540 //UnRegistering because of 137896: Inside tab control multiple Loaded events happen without an Unloaded event.
541 this.typePresenter.TypeBrowserClosed -= OnTypePresenterTypeBrowserClosed;
542 this.typePresenter.TypeBrowserClosed += OnTypePresenterTypeBrowserClosed;
545 void OnTypePresenterUnloaded(object sender, RoutedEventArgs e)
547 if (this.typePresenter != null)
549 this.typePresenter.TypeBrowserClosed -= OnTypePresenterTypeBrowserClosed;
550 this.typePresenter = null;
554 void OnTypePresenterTypeBrowserClosed(object sender, RoutedEventArgs e)
556 this.typePresenter.FocusOnVisibleControl();
559 void OnTypePresenterKeyDown(object sender, KeyEventArgs e)
561 switch (e.Key)
563 case Key.Escape:
564 this.SwitchToHintText();
565 e.Handled = true;
566 break;
568 case Key.Enter:
569 this.AddCatch();
570 e.Handled = true;
571 break;
575 void OnTypePresenterLostFocus(object sender, RoutedEventArgs e)
577 if (this.ShowTypePresenterExpanded)
579 this.AddCatch();
580 e.Handled = true;
584 void AddCatch()
586 if (this.typePresenter != null)
588 Type type = this.typePresenter.Type;
589 if (type != null && this.ExceptionTypeFilter(type))
591 CreateCatch(type);
593 this.SwitchToHintText();
597 #endregion
599 bool ExceptionTypeFilter(Type type)
601 if (type == null)
603 return false;
606 if (type != typeof(Exception) && !type.IsSubclassOf(typeof(Exception)))
608 return false;
611 ModelProperty catchesProperty = this.ModelItem.Properties[CatchesPropertyName];
612 Fx.Assert(catchesProperty != null, "TryCatch.Catches could not be null");
613 ModelItemCollection catches = catchesProperty.Collection;
614 Fx.Assert(catches != null, "Catches.Collection could not be null");
615 foreach (ModelItem catchItem in catches)
617 ModelProperty exceptionTypeProperty = catchItem.Properties[ExceptionTypePropertyName];
618 Fx.Assert(exceptionTypeProperty != null, "Catch.ExceptionType could not be null");
619 Type exceptionType = exceptionTypeProperty.ComputedValue as Type;
620 Fx.Assert(exceptionType != null, "Catch.ExceptionType.Value could not be null");
622 if (exceptionType == type)
624 return false;
628 return true;
632 internal class TextBlockWrapper : TextBlock
634 protected override AutomationPeer OnCreateAutomationPeer()
636 if (!LocalAppContextSwitches.UseLegacyAccessibilityFeatures)
638 return new TextBlockWrapperAutomationPeer(this);
640 return base.OnCreateAutomationPeer();
644 internal class TextBlockWrapperAutomationPeer : TextBlockAutomationPeer
646 public TextBlockWrapperAutomationPeer(TextBlockWrapper owner)
647 : base(owner)
651 protected override AutomationControlType GetAutomationControlTypeCore()
653 return AutomationControlType.Button;