PageRenderTime 41ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/V2.2/trunk/CAL/Desktop/Composite.Presentation/Regions/Behaviors/SyncRegionContextWithHostBehavior.cs

#
C# | 125 lines | 72 code | 10 blank | 43 comment | 13 complexity | 85a4def8ac96d7ce23a09676874522a4 MD5 | raw file
  1. //===================================================================================
  2. // Microsoft patterns & practices
  3. // Composite Application Guidance for Windows Presentation Foundation and Silverlight
  4. //===================================================================================
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
  7. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
  8. // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  9. // FITNESS FOR A PARTICULAR PURPOSE.
  10. //===================================================================================
  11. // The example companies, organizations, products, domain names,
  12. // e-mail addresses, logos, people, places, and events depicted
  13. // herein are fictitious. No association with any real company,
  14. // organization, product, domain name, email address, logo, person,
  15. // places, or events is intended or should be inferred.
  16. //===================================================================================
  17. using System;
  18. using System.Windows;
  19. using Microsoft.Practices.Composite.Presentation.Properties;
  20. using Microsoft.Practices.Composite.Regions;
  21. namespace Microsoft.Practices.Composite.Presentation.Regions.Behaviors
  22. {
  23. /// <summary>
  24. /// Behavior that synchronizes the <see cref="IRegion.Context"/> property of a <see cref="IRegion"/> with
  25. /// the control that hosts the Region. It does this by setting the <see cref="RegionManager.RegionContextProperty"/>
  26. /// Dependency Property on the host control.
  27. ///
  28. /// This behavior allows the usage of two way databinding of the RegionContext from XAML.
  29. /// </summary>
  30. public class SyncRegionContextWithHostBehavior : RegionBehavior, IHostAwareRegionBehavior
  31. {
  32. private const string RegionContextPropertyName = "Context";
  33. private DependencyObject hostControl;
  34. /// <summary>
  35. /// Name that identifies the SyncRegionContextWithHostBehavior behavior in a collection of RegionsBehaviors.
  36. /// </summary>
  37. public static readonly string BehaviorKey = "SyncRegionContextWithHost";
  38. private ObservableObject<object> HostControlRegionContext
  39. {
  40. get
  41. {
  42. return RegionContext.GetObservableContext(this.hostControl);
  43. }
  44. }
  45. /// <summary>
  46. /// Gets or sets the <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
  47. /// </summary>
  48. /// <value>
  49. /// A <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
  50. /// This is usually a <see cref="FrameworkElement"/> that is part of the tree.
  51. /// </value>
  52. public DependencyObject HostControl
  53. {
  54. get
  55. {
  56. return hostControl;
  57. }
  58. set
  59. {
  60. if (IsAttached)
  61. {
  62. throw new InvalidOperationException(Resources.HostControlCannotBeSetAfterAttach);
  63. }
  64. this.hostControl = value;
  65. }
  66. }
  67. /// <summary>
  68. /// Override this method to perform the logic after the behavior has been attached.
  69. /// </summary>
  70. protected override void OnAttach()
  71. {
  72. if (this.HostControl != null)
  73. {
  74. // Sync values initially.
  75. SynchronizeRegionContext();
  76. // Now register for events to keep them in sync
  77. this.HostControlRegionContext.PropertyChanged += this.RegionContextObservableObject_PropertyChanged;
  78. this.Region.PropertyChanged += this.Region_PropertyChanged;
  79. }
  80. }
  81. void Region_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
  82. {
  83. if (e.PropertyName == RegionContextPropertyName)
  84. {
  85. if (RegionManager.GetRegionContext(this.HostControl) != this.Region.Context)
  86. {
  87. // Setting this DP will automatically also change the HostControlRegionContext.Value
  88. // (see RegionManager.OnRegionContextChanged())
  89. RegionManager.SetRegionContext(this.hostControl, this.Region.Context);
  90. }
  91. }
  92. }
  93. void RegionContextObservableObject_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
  94. {
  95. if (e.PropertyName == "Value")
  96. {
  97. SynchronizeRegionContext();
  98. }
  99. }
  100. private void SynchronizeRegionContext()
  101. {
  102. // Forward this value to the Region
  103. if (this.Region.Context != this.HostControlRegionContext.Value)
  104. {
  105. this.Region.Context = this.HostControlRegionContext.Value;
  106. }
  107. // Also make sure the region's DependencyProperty was changed (this can occur if the value
  108. // was changed only on the HostControlRegionContext)
  109. if (RegionManager.GetRegionContext(this.HostControl) != this.HostControlRegionContext.Value)
  110. {
  111. RegionManager.SetRegionContext(this.HostControl, this.HostControlRegionContext.Value);
  112. }
  113. }
  114. }
  115. }