PageRenderTime 42ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/V4/PrismLibrary/Desktop/Prism/Regions/Behaviors/SyncRegionContextWithHostBehavior.cs

#
C# | 124 lines | 71 code | 10 blank | 43 comment | 13 complexity | 365011e7dee784525468d8e8e063539f 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.Prism.Properties;
  20. namespace Microsoft.Practices.Prism.Regions.Behaviors
  21. {
  22. /// <summary>
  23. /// Behavior that synchronizes the <see cref="IRegion.Context"/> property of a <see cref="IRegion"/> with
  24. /// the control that hosts the Region. It does this by setting the <see cref="RegionManager.RegionContextProperty"/>
  25. /// Dependency Property on the host control.
  26. ///
  27. /// This behavior allows the usage of two way databinding of the RegionContext from XAML.
  28. /// </summary>
  29. public class SyncRegionContextWithHostBehavior : RegionBehavior, IHostAwareRegionBehavior
  30. {
  31. private const string RegionContextPropertyName = "Context";
  32. private DependencyObject hostControl;
  33. /// <summary>
  34. /// Name that identifies the SyncRegionContextWithHostBehavior behavior in a collection of RegionsBehaviors.
  35. /// </summary>
  36. public static readonly string BehaviorKey = "SyncRegionContextWithHost";
  37. private ObservableObject<object> HostControlRegionContext
  38. {
  39. get
  40. {
  41. return RegionContext.GetObservableContext(this.hostControl);
  42. }
  43. }
  44. /// <summary>
  45. /// Gets or sets the <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
  46. /// </summary>
  47. /// <value>
  48. /// A <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
  49. /// This is usually a <see cref="FrameworkElement"/> that is part of the tree.
  50. /// </value>
  51. public DependencyObject HostControl
  52. {
  53. get
  54. {
  55. return hostControl;
  56. }
  57. set
  58. {
  59. if (IsAttached)
  60. {
  61. throw new InvalidOperationException(Resources.HostControlCannotBeSetAfterAttach);
  62. }
  63. this.hostControl = value;
  64. }
  65. }
  66. /// <summary>
  67. /// Override this method to perform the logic after the behavior has been attached.
  68. /// </summary>
  69. protected override void OnAttach()
  70. {
  71. if (this.HostControl != null)
  72. {
  73. // Sync values initially.
  74. SynchronizeRegionContext();
  75. // Now register for events to keep them in sync
  76. this.HostControlRegionContext.PropertyChanged += this.RegionContextObservableObject_PropertyChanged;
  77. this.Region.PropertyChanged += this.Region_PropertyChanged;
  78. }
  79. }
  80. void Region_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
  81. {
  82. if (e.PropertyName == RegionContextPropertyName)
  83. {
  84. if (RegionManager.GetRegionContext(this.HostControl) != this.Region.Context)
  85. {
  86. // Setting this Dependency Property will automatically also change the HostControlRegionContext.Value
  87. // (see RegionManager.OnRegionContextChanged())
  88. RegionManager.SetRegionContext(this.hostControl, this.Region.Context);
  89. }
  90. }
  91. }
  92. void RegionContextObservableObject_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
  93. {
  94. if (e.PropertyName == "Value")
  95. {
  96. SynchronizeRegionContext();
  97. }
  98. }
  99. private void SynchronizeRegionContext()
  100. {
  101. // Forward this value to the Region
  102. if (this.Region.Context != this.HostControlRegionContext.Value)
  103. {
  104. this.Region.Context = this.HostControlRegionContext.Value;
  105. }
  106. // Also make sure the region's DependencyProperty was changed (this can occur if the value
  107. // was changed only on the HostControlRegionContext)
  108. if (RegionManager.GetRegionContext(this.HostControl) != this.HostControlRegionContext.Value)
  109. {
  110. RegionManager.SetRegionContext(this.HostControl, this.HostControlRegionContext.Value);
  111. }
  112. }
  113. }
  114. }