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
;
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
;
28 /// Interaction logic for TryCatchDesigner.xaml
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(
40 typeof(TryCatchDesigner
),
41 new UIPropertyMetadata(true)
44 public static readonly DependencyProperty ShowFinallyExpandedProperty
=
45 DependencyProperty
.Register(
46 "ShowFinallyExpanded",
48 typeof(TryCatchDesigner
),
49 new UIPropertyMetadata(false)
52 public static readonly DependencyProperty ShowTypePresenterExpandedProperty
=
53 DependencyProperty
.Register(
54 "ShowTypePresenterExpanded",
56 typeof(TryCatchDesigner
),
57 new UIPropertyMetadata(false)
60 public static readonly DependencyProperty SelectedCatchProperty
=
61 DependencyProperty
.Register(
64 typeof(TryCatchDesigner
),
65 new UIPropertyMetadata(null));
67 static ObservableCollection
<Type
> mostRecentlyUsedTypes
;
68 static ObservableCollection
<Type
> MostRecentlyUsedTypes
72 if (mostRecentlyUsedTypes
== null)
74 mostRecentlyUsedTypes
= new ObservableCollection
<Type
>
76 typeof(ArgumentException
),
77 typeof(NullReferenceException
),
79 typeof(InvalidOperationException
),
83 return mostRecentlyUsedTypes
;
87 public bool ShowTryExpanded
91 return (bool)this.GetValue(ShowTryExpandedProperty
);
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
;
176 CollapseFinallyView();
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
)
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();
224 foreach (ModelItem catchObject
in this.ModelItem
.Properties
["Catches"].Collection
)
226 if (IsDescendantOfCatch(catchObject
, selection
.PrimarySelection
))
228 UpdateSelection(catchObject
);
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)
252 ModelItem itr
= descendant
;
264 bool IsDescendantOf(ModelItem descendant
, string property
)
266 if (descendant
== null)
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
)
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
);
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)
318 CollapseFinallyView();
319 CatchDesigner newSelectedCatchDesigner
= (CatchDesigner
)newSelectedCatch
.View
;
320 if (newSelectedCatchDesigner
!= null)
322 newSelectedCatchDesigner
.ExpandState
= true;
323 newSelectedCatchDesigner
.PinState
= true;
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);
359 else if (e
.LeftButton
== MouseButtonState
.Pressed
)
362 Keyboard
.Focus((IInputElement
)sender
);
364 else if (e
.RightButton
== MouseButtonState
.Pressed
)
366 if (this.IsExpanded(this.ShowFinallyExpanded
))
368 Keyboard
.Focus((IInputElement
)sender
);
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
)
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);
396 else if (e
.LeftButton
== MouseButtonState
.Pressed
)
399 Keyboard
.Focus((IInputElement
)sender
);
401 else if (e
.RightButton
== MouseButtonState
.Pressed
)
403 if (this.IsExpanded(this.ShowTryExpanded
))
405 Keyboard
.Focus((IInputElement
)sender
);
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
)
420 void ExpandFinallyView()
422 UpdateSelection(null);
423 this.Dispatcher
.BeginInvoke(DispatcherPriority
.Normal
, (Action
)(() =>
425 this.ShowTryExpanded
= false;
426 this.ShowFinallyExpanded
= true;
432 UpdateSelection(null);
433 this.Dispatcher
.BeginInvoke(DispatcherPriority
.Normal
, (Action
)(() =>
435 this.ShowFinallyExpanded
= false;
436 this.ShowTryExpanded
= true;
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
))
459 void OnTryAddActivityKeyDown(object sender
, KeyEventArgs e
)
461 if (!LocalAppContextSwitches
.UseLegacyAccessibilityFeatures
)
463 if (sender
== e
.OriginalSource
&& (e
.Key
== Key
.Space
|| e
.Key
== Key
.Enter
))
471 void OnFinallyViewKeyDown(object sender
, KeyEventArgs e
)
473 if (sender
== e
.OriginalSource
&& (e
.Key
== Key
.Space
|| e
.Key
== Key
.Enter
))
480 void OnFinallyAddActivityKeyDown(object sender
, KeyEventArgs e
)
482 if (!LocalAppContextSwitches
.UseLegacyAccessibilityFeatures
)
484 if (sender
== e
.OriginalSource
&& (e
.Key
== Key
.Space
|| e
.Key
== Key
.Enter
))
492 #region AddCatch Label & TypePresenter
494 void OnAddCatchMouseDown(object sender
, MouseButtonEventArgs e
)
496 if (e
.LeftButton
== MouseButtonState
.Pressed
)
498 this.SwitchToChooseException();
503 void OnAddCatchGotFocus(object sender
, RoutedEventArgs e
)
505 this.SwitchToChooseException();
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
)
564 this.SwitchToHintText();
575 void OnTypePresenterLostFocus(object sender
, RoutedEventArgs e
)
577 if (this.ShowTypePresenterExpanded
)
586 if (this.typePresenter
!= null)
588 Type type
= this.typePresenter
.Type
;
589 if (type
!= null && this.ExceptionTypeFilter(type
))
593 this.SwitchToHintText();
599 bool ExceptionTypeFilter(Type type
)
606 if (type
!= typeof(Exception
) && !type
.IsSubclassOf(typeof(Exception
)))
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
)
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
)
651 protected override AutomationControlType
GetAutomationControlTypeCore()
653 return AutomationControlType
.Button
;