1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //----------------------------------------------------------------
4 namespace System.Activities.Presentation.Internal.PropertyEditing
7 using System.ComponentModel;
8 using System.Diagnostics;
9 using System.Diagnostics.CodeAnalysis;
11 using System.Windows.Automation.Peers;
12 using System.Windows.Controls;
15 using System.Activities.Presentation.Internal.PropertyEditing.Automation;
16 using System.Activities.Presentation.Internal.PropertyEditing.State;
17 using System.Activities.Presentation.Internal.PropertyEditing.Views;
20 // Container control that hosts both the property-search UI as well as the view-switching UI
22 internal sealed class PropertyToolBar : Control, INotifyPropertyChanged
26 // Property representing the currently-selected IPropertyViewManager
28 public static DependencyProperty CurrentViewManagerProperty = DependencyProperty.Register(
30 typeof(IPropertyViewManager),
31 typeof(PropertyToolBar),
32 new PropertyMetadata(null, OnCurrentViewManagerChanged));
35 // Property containing a link to the CategoryList control instance that this
36 // PropertyToolBar controls. We need this link to be able to change the appearance
37 // of each new generated CategoryContainer (whether it should show a header or not).
38 // That way CategoryList doesn't need to know anything about this class.
40 public static DependencyProperty CategoryListProperty = DependencyProperty.Register(
43 typeof(PropertyToolBar),
44 new PropertyMetadata(null, OnCategoryListChanged));
46 private string _persistenceId;
47 private bool _persistViewManagerChanges = true;
49 public PropertyToolBar()
51 this.Loaded += new RoutedEventHandler(OnLoaded);
52 this.Unloaded += new RoutedEventHandler(OnUnloaded);
56 // Event we fire when the CurrentViewManager changes
58 public event EventHandler CurrentViewManagerChanged;
60 public event PropertyChangedEventHandler PropertyChanged;
63 // Gets or set the currently selected IPropertyViewManager
65 public IPropertyViewManager CurrentViewManager
67 get { return (IPropertyViewManager)this.GetValue(CurrentViewManagerProperty); }
68 set { this.SetValue(CurrentViewManagerProperty, value); }
72 // Gets or set the value of the CategoryListProperty
74 public CategoryList CategoryList
76 get { return (CategoryList)this.GetValue(CategoryListProperty); }
77 set { this.SetValue(CategoryListProperty, value); }
81 // Gets or sets a string ID that we use to differentiate between the states of different
82 // PropertyToolBar instances. Currently, we only care about two different PropertyToolBar
83 // buckets - (1) the PTBs we use in the main PI and (2) the PTBs we use in collection editors.
85 public string PersistenceId
88 return _persistenceId;
91 if (_persistenceId != value)
93 _persistenceId = value;
95 if (this.CurrentViewManager == null)
97 bool oldPersistViewManagerChanges = _persistViewManagerChanges;
100 _persistViewManagerChanges = false;
101 this.CurrentViewManager = PropertyViewManagerStateContainer.Instance.GetPropertyViewManager(_persistenceId);
105 _persistViewManagerChanges = oldPersistViewManagerChanges;
109 OnPropertyChanged("PersistenceId");
115 // Convenience accessor for the UI data binding
117 public bool IsCategoryViewSelected
120 if (this.CurrentViewManager != null)
122 return this.CurrentViewManager == ByCategoryViewManager.Instance;
128 // No need to fire PropertyChanged events here - changing CurrentViewManager
129 // will fire those events as a side-effect
131 if (this.CurrentViewManager == ByCategoryViewManager.Instance ^ value)
135 this.CurrentViewManager = ByCategoryViewManager.Instance;
139 this.CurrentViewManager = AlphabeticalViewManager.Instance;
146 // Convenience accessor for the UI data binding
148 public bool IsAlphaViewSelected
151 if (this.CurrentViewManager != null)
153 return this.CurrentViewManager == AlphabeticalViewManager.Instance;
159 // No need to fire PropertyChanged events here - changing CurrentViewManager
160 // will fire those events as a side-effect
162 if (this.CurrentViewManager == AlphabeticalViewManager.Instance ^ value)
166 this.CurrentViewManager = AlphabeticalViewManager.Instance;
170 this.CurrentViewManager = ByCategoryViewManager.Instance;
176 // AutomationPeer Stuff
178 internal RadioButton ByCategoryViewButton
179 { get { return VisualTreeUtils.GetNamedChild<RadioButton>(this, "PART_ByCategoryViewButton"); } }
180 internal RadioButton AlphaViewButton
181 { get { return VisualTreeUtils.GetNamedChild<RadioButton>(this, "PART_AlphaViewButton"); } }
182 internal TextBlock SearchLabel
183 { get { return VisualTreeUtils.GetNamedChild<TextBlock>(this, "PART_SearchLabel"); } }
184 internal TextBox SearchTextBox
185 { get { return VisualTreeUtils.GetNamedChild<TextBox>(this, "PART_SearchTextBox"); } }
186 internal Button SearchClearButton
187 { get { return VisualTreeUtils.GetNamedChild<Button>(this, "PART_SearchClearButton"); } }
189 private void OnLoaded(object sender, RoutedEventArgs e)
191 PropertyViewManagerStateContainer.Instance.ContentRestored += new EventHandler(OnGlobalPropertyViewManagerRestored);
194 private void OnUnloaded(object sender, RoutedEventArgs e)
196 PropertyViewManagerStateContainer.Instance.ContentRestored -= new EventHandler(OnGlobalPropertyViewManagerRestored);
199 private void OnGlobalPropertyViewManagerRestored(object sender, EventArgs e)
202 // If the state of PropertyViewManagerStateContainer has been restored
203 // update the current view of the PropertyToolBar based on the restored state
205 if (this.PersistenceId != null)
207 bool oldPersistViewManagerChanges = _persistViewManagerChanges;
210 _persistViewManagerChanges = false;
211 this.CurrentViewManager = PropertyViewManagerStateContainer.Instance.GetPropertyViewManager(this.PersistenceId);
215 _persistViewManagerChanges = oldPersistViewManagerChanges;
220 // CurrentViewManager DP
222 private static void OnCurrentViewManagerChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
224 PropertyToolBar theThis = obj as PropertyToolBar;
230 theThis.OnPropertyChanged("IsCategoryViewSelected");
231 theThis.OnPropertyChanged("IsAlphaViewSelected");
233 // Store and persist the CurrentViewManager value only if:
235 // * this change did not come from PropertyViewManagerStateContainer itself
236 // * we have a persistence ID to differentiate this control instance by
237 // * this is not the first time the value was set - in other words, only
238 // store values that were triggered by the user making a conscious change
240 if (theThis.PersistenceId != null && theThis._persistViewManagerChanges && e.OldValue != null)
242 PropertyViewManagerStateContainer.Instance.StorePropertyViewManager(theThis.PersistenceId, e.NewValue as IPropertyViewManager);
245 // fire this event after we have stored the propertyviewmanager, so that the StateChanged event will get
246 // the updated view-manager
247 if (theThis.CurrentViewManagerChanged != null)
249 theThis.CurrentViewManagerChanged(theThis, EventArgs.Empty);
253 if (null != theThis.CategoryList)
255 theThis.CategoryList.RefreshFilter();
264 private static void OnCategoryListChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
266 PropertyToolBar theThis = obj as PropertyToolBar;
272 if (e.OldValue != null)
274 theThis.UnhookEvents(e.OldValue as CategoryList);
277 if (e.NewValue != null)
279 theThis.HookEvents(e.NewValue as CategoryList);
283 private void HookEvents(CategoryList categoryList)
285 if (categoryList == null)
287 Debug.Fail("This method shouldn't be called when there is no CategoryList instance to process.");
291 categoryList.ContainerGenerated += new ContainerGeneratedHandler(OnCategoryContainerGenerated);
294 private void UnhookEvents(CategoryList categoryList)
296 if (categoryList == null)
298 Debug.Fail("This method shouldn't be called when there is no CategoryList instance to process.");
302 categoryList.ContainerGenerated -= new ContainerGeneratedHandler(OnCategoryContainerGenerated);
305 private void OnCategoryContainerGenerated(object sender, ContainerGeneratedEventArgs e)
307 if (e.Container == null)
311 e.Container.ShowCategoryHeader = this.CurrentViewManager == null ? true : this.CurrentViewManager.ShowCategoryHeaders;
316 protected override AutomationPeer OnCreateAutomationPeer()
318 return new UIElementAutomationPeer(this);
323 // INotifyPropertyChanged Members
325 private void OnPropertyChanged(string propertyName)
327 if (PropertyChanged != null)
329 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));