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