PageRenderTime 36ms CodeModel.GetById 21ms app.highlight 9ms RepoModel.GetById 2ms 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//===================================================================================
 17using System;
 18using System.Windows;
 19using Microsoft.Practices.Prism.Properties;
 20
 21namespace Microsoft.Practices.Prism.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
 35        /// <summary>
 36        /// Name that identifies the SyncRegionContextWithHostBehavior behavior in a collection of RegionsBehaviors. 
 37        /// </summary>
 38        public static readonly string BehaviorKey = "SyncRegionContextWithHost";
 39
 40        private ObservableObject<object> HostControlRegionContext
 41        {
 42            get
 43            {
 44                return RegionContext.GetObservableContext(this.hostControl);
 45            }
 46        }
 47
 48        /// <summary>
 49        /// Gets or sets the <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
 50        /// </summary>
 51        /// <value>
 52        /// A <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
 53        /// This is usually a <see cref="FrameworkElement"/> that is part of the tree.
 54        /// </value>
 55        public DependencyObject HostControl
 56        {
 57            get
 58            {
 59                return hostControl;
 60            }
 61            set
 62            {
 63                if (IsAttached)
 64                {
 65                    throw new InvalidOperationException(Resources.HostControlCannotBeSetAfterAttach);
 66                }
 67                this.hostControl = value;
 68            }
 69        }
 70
 71        /// <summary>
 72        /// Override this method to perform the logic after the behavior has been attached.
 73        /// </summary>
 74        protected override void OnAttach()
 75        {
 76            if (this.HostControl != null)
 77            {
 78                // Sync values initially. 
 79                SynchronizeRegionContext();
 80
 81                // Now register for events to keep them in sync
 82                this.HostControlRegionContext.PropertyChanged += this.RegionContextObservableObject_PropertyChanged;
 83                this.Region.PropertyChanged += this.Region_PropertyChanged;
 84            }
 85        }
 86
 87        void Region_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
 88        {
 89            if (e.PropertyName == RegionContextPropertyName)
 90            {
 91                if (RegionManager.GetRegionContext(this.HostControl) != this.Region.Context)
 92                {
 93                    // Setting this Dependency Property will automatically also change the HostControlRegionContext.Value
 94                    // (see RegionManager.OnRegionContextChanged())
 95                    RegionManager.SetRegionContext(this.hostControl, this.Region.Context);
 96                }
 97            }
 98        }
 99
100        void RegionContextObservableObject_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
101        {
102            if (e.PropertyName == "Value")
103            {
104                SynchronizeRegionContext();
105            }
106        }
107
108        private void SynchronizeRegionContext()
109        {
110            // Forward this value to the Region
111            if (this.Region.Context != this.HostControlRegionContext.Value)
112            {
113                this.Region.Context = this.HostControlRegionContext.Value;
114            }
115
116            // Also make sure the region's DependencyProperty was changed (this can occur if the value
117            // was changed only on the HostControlRegionContext)
118            if (RegionManager.GetRegionContext(this.HostControl) != this.HostControlRegionContext.Value)
119            {
120                RegionManager.SetRegionContext(this.HostControl, this.HostControlRegionContext.Value);
121            }
122        }
123    }
124}