[corlib] Avoid unnecessary ephemeron array resizes
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / View / TreeView / DesignerTreeViewItem.cs
1 
2 //----------------------------------------------------------------
3 // Copyright (c) Microsoft Corporation.  All rights reserved.
4 //----------------------------------------------------------------
5
6 namespace System.Activities.Presentation.View.TreeView
7 {
8     using System.Activities.Presentation.Model;
9     using System.Collections;
10     using System.Collections.Generic;
11     using System.ComponentModel;
12     using System.Runtime;
13     using System.Text;
14     using System.Windows;
15     using System.Windows.Automation.Peers;
16     using System.Windows.Controls;
17     using System.Windows.Data;
18
19     class DesignerTreeViewItem : TreeViewItem, ITreeViewItemSelectionHandler
20     {
21         private bool shouldUpdateViewModel = true;
22
23         public DesignerTreeView ParentTreeView { get; set; }
24
25         protected override AutomationPeer OnCreateAutomationPeer()
26         {
27             return new DesignerTreeViewItemAutomationPeer(this);
28         }
29
30         protected override void OnItemsChanged(Collections.Specialized.NotifyCollectionChangedEventArgs e)
31         {
32             if (e.Action == Collections.Specialized.NotifyCollectionChangedAction.Remove)
33             {
34                 // Don't select itself when its child items got removed. (Default action of base.OnItemsChanged)
35                 // The selection should be managed by designer surface.
36                 return;
37             }
38
39             base.OnItemsChanged(e);
40         }
41
42         internal Dictionary<string, string> GetAutomationItemStatus()
43         {
44             Dictionary<string, string> itemStatus = new Dictionary<string, string>();
45             TreeViewItemViewModel viewModel = this.Header as TreeViewItemViewModel;
46             if (viewModel != null && viewModel.IsHighlighted)
47             {
48                 itemStatus.Add("IsSelection", "True");
49             }
50             else
51             {
52                 itemStatus.Add("IsSelection", "False");
53             }
54
55             return itemStatus;
56         }
57
58         protected override Windows.DependencyObject GetContainerForItemOverride()
59         {
60             DesignerTreeViewItem item = new DesignerTreeViewItem() { ParentTreeView = this.ParentTreeView };
61             return item;
62         }
63
64         protected override void OnHeaderChanged(object oldHeader, object newHeader)
65         {
66             base.OnHeaderChanged(oldHeader, newHeader);
67
68             TreeViewItemViewModel source = newHeader as TreeViewItemViewModel;
69             if (source != null)
70             {
71                 source.TreeViewItem = this;
72             }
73         }
74
75         protected override void OnSelected(Windows.RoutedEventArgs e)
76         {
77             base.OnSelected(e);
78             ParentTreeView.IsSelectionChangeHandledByTreeView = true;
79             UpdateTreeViewItemViewModel();
80         }
81
82         protected override void OnUnselected(RoutedEventArgs e)
83         {
84             base.OnUnselected(e);
85             if (shouldUpdateViewModel)
86             {
87                 TreeViewItemViewModel viewModel = this.Header as TreeViewItemViewModel;
88                 if (viewModel != null)
89                 {
90                     if (viewModel is TreeViewItemModelPropertyViewModel || viewModel is TreeViewItemKeyValuePairModelItemViewModel)
91                     {
92                         viewModel.IsHighlighted = false;
93                     }
94                     else if (viewModel is TreeViewItemModelItemViewModel)
95                     {
96                         TreeViewItemModelItemViewModel modelItemViewModel = (TreeViewItemModelItemViewModel)viewModel;
97                         if (!modelItemViewModel.HasDesigner)
98                         {
99                             modelItemViewModel.IsHighlighted = false;
100                         }
101                     }
102                 }
103             }
104         }
105
106         private void UpdateTreeViewItemViewModel()
107         {
108             if (!shouldUpdateViewModel)
109             {
110                 return;
111             }
112
113             if (this.Header is TreeViewItemModelItemViewModel)
114             {
115                 TreeViewItemModelItemViewModel modelItemViewModel = (TreeViewItemModelItemViewModel)this.Header;
116                 if (modelItemViewModel.HasDesigner)
117                 {
118                     HighlightModelItemOnDesigner(modelItemViewModel.VisualValue);
119                 }
120                 else
121                 {
122                     HighlightTreeViewItemAndClearSelectionOnDesigner(modelItemViewModel);
123                 }
124             }
125             else if (this.Header is TreeViewItemModelPropertyViewModel)
126             {
127                 TreeViewItemModelPropertyViewModel modelPropertyViewModel = (TreeViewItemModelPropertyViewModel)this.Header;
128                 HighlightTreeViewItemAndClearSelectionOnDesigner(modelPropertyViewModel);
129             }
130             else if (this.Header is TreeViewItemKeyValuePairModelItemViewModel)
131             {
132                 TreeViewItemKeyValuePairModelItemViewModel keyValuePairItem = (TreeViewItemKeyValuePairModelItemViewModel)this.Header;
133                 HighlightTreeViewItemAndClearSelectionOnDesigner(keyValuePairItem);
134             }
135             else
136             {
137                 Fx.Assert("Invaild logic if Header is not TreeViewItemModelItemViewModel/TreeViewItemModelPropertyViewModel/TreeViewItemDictionaryModelItemViewModel");
138             }
139         }
140
141         private void HighlightModelItemOnDesigner(ModelItem selectedModelItem)
142         {
143             if (selectedModelItem != null)
144             {
145                 Selection.SelectOnly(this.ParentTreeView.Context, selectedModelItem);
146                 // Set highlight to visual value.  
147                 // Don't use "Focus()" since it will steal keyboard focus and disable 
148                 // keyboard navigation.
149                 selectedModelItem.Highlight();
150             }
151         }
152
153         private void HighlightTreeViewItemAndClearSelectionOnDesigner(TreeViewItemViewModel viewModel)
154         {
155             this.ParentTreeView.Context.Items.SetValue(new Selection());
156             viewModel.IsHighlighted = true;
157         }
158
159         void ITreeViewItemSelectionHandler.Select()
160         {
161             // Invoked from ViewModel, needn't update ViewModel again.
162             shouldUpdateViewModel = false;
163             this.IsSelected = true;
164             shouldUpdateViewModel = true;
165         }
166
167         void ITreeViewItemSelectionHandler.Unselect()
168         {
169             // Invoked from ViewModel, needn't update ViewModel again.
170             shouldUpdateViewModel = false;
171             this.IsSelected = false;
172             shouldUpdateViewModel = true;
173         }
174
175         private class DesignerTreeViewItemAutomationPeer : TreeViewItemAutomationPeer
176         {
177             private DesignerTreeViewItem owner;
178
179             public DesignerTreeViewItemAutomationPeer(DesignerTreeViewItem owner)
180                 : base(owner)
181             {
182                 Fx.Assert(owner != null, "DesignerTreeViewItemAutomationPeer should not accept a null owner.");
183                 this.owner = owner;
184             }
185
186             protected override AutomationControlType GetAutomationControlTypeCore()
187             {
188                 return AutomationControlType.TreeItem;
189             }
190
191             protected override string GetItemStatusCore()
192             {
193                 Dictionary<string, string> itemStatus = this.owner.GetAutomationItemStatus();
194                 StringBuilder builder = new StringBuilder();
195                 foreach (KeyValuePair<string, string> item in itemStatus)
196                 {
197                     builder.AppendFormat("{0}={1} ", item.Key, item.Value);
198                 }
199
200                 return builder.ToString();
201             }
202         }
203     }
204 }