The Labs \ Source Viewer \ SSCLI \ System.ComponentModel \ NestedContainer

  1. //------------------------------------------------------------------------------
  2. // <copyright file="NestedContainer.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.ComponentModel
  16. {
  17.    
  18.     using System;
  19.     using System.ComponentModel;
  20.     using System.Globalization;
  21.     using System.IO;
  22.     using System.Security.Permissions;
  23.    
  24.     /// <devdoc>
  25.     /// A nested container is a container that is owned by another component. Nested
  26.     /// containers can be found by querying a component site's services for NestedConainter.
  27.     /// Nested containers are a useful tool to establish owner relationships among components.
  28.     /// All components within a nested container are named with the owning component's name
  29.     /// as a prefix.
  30.     /// </devdoc>
  31.     [HostProtection(SharedState = true)]
  32.     public class NestedContainer : Container, INestedContainer
  33.     {
  34.        
  35.         private IComponent _owner;
  36.        
  37.         /// <devdoc>
  38.         /// Creates a new NestedContainer.
  39.         /// </devdoc>
  40.         public NestedContainer(IComponent owner)
  41.         {
  42.             if (owner == null) {
  43.                 throw new ArgumentNullException("owner");
  44.             }
  45.             _owner = owner;
  46.             _owner.Disposed += new EventHandler(OnOwnerDisposed);
  47.         }
  48.        
  49.         /// <devdoc>
  50.         /// The component that owns this nested container.
  51.         /// </devdoc>
  52.         public IComponent Owner {
  53.             get { return _owner; }
  54.         }
  55.        
  56.         /// <devdoc>
  57.         /// Retrieves the name of the owning component. This may be overridden to
  58.         /// provide a custom owner name. The default searches the owner's site for
  59.         /// INestedSite and calls FullName, or ISite.Name if there is no nested site.
  60.         /// If neither is available, this returns null.
  61.         /// </devdoc>
  62.         protected virtual string OwnerName {
  63.             get {
  64.                 string ownerName = null;
  65.                 if (_owner != null && _owner.Site != null) {
  66.                     INestedSite nestedOwnerSite = _owner.Site as INestedSite;
  67.                     if (nestedOwnerSite != null) {
  68.                         ownerName = nestedOwnerSite.FullName;
  69.                     }
  70.                     else {
  71.                         ownerName = _owner.Site.Name;
  72.                     }
  73.                 }
  74.                
  75.                 return ownerName;
  76.             }
  77.         }
  78.        
  79.         /// <devdoc>
  80.         /// Creates a site for the component within the container.
  81.         /// </devdoc>
  82.         protected override ISite CreateSite(IComponent component, string name)
  83.         {
  84.             if (component == null) {
  85.                 throw new ArgumentNullException("component");
  86.             }
  87.             return new Site(component, this, name);
  88.         }
  89.        
  90.         /// <devdoc>
  91.         /// Override of Container's dispose.
  92.         /// </devdoc>
  93.         protected override void Dispose(bool disposing)
  94.         {
  95.             if (disposing) {
  96.                 _owner.Disposed -= new EventHandler(OnOwnerDisposed);
  97.             }
  98.             base.Dispose(disposing);
  99.         }
  100.        
  101.         /// <devdoc>
  102.         /// <para>[To be supplied.]</para>
  103.         /// </devdoc>
  104.         protected override object GetService(Type service)
  105.         {
  106.             if (service == typeof(INestedContainer)) {
  107.                 return this;
  108.             }
  109.             else {
  110.                 return base.GetService(service);
  111.             }
  112.         }
  113.        
  114.         /// <devdoc>
  115.         /// Called when our owning component is destroyed.
  116.         /// </devdoc>
  117.         private void OnOwnerDisposed(object sender, EventArgs e)
  118.         {
  119.             Dispose();
  120.         }
  121.        
  122.         /// <devdoc>
  123.         /// Simple site implementation. We do some special processing to name the site, but
  124.         /// that's about it.
  125.         /// </devdoc>
  126.         private class Site : INestedSite
  127.         {
  128.             private IComponent component;
  129.             private NestedContainer container;
  130.             private string name;
  131.            
  132.             internal Site(IComponent component, NestedContainer container, string name)
  133.             {
  134.                 this.component = component;
  135.                 this.container = container;
  136.                 this.name = name;
  137.             }
  138.            
  139.             // The component sited by this component site.
  140.             public IComponent Component {
  141.                 get { return component; }
  142.             }
  143.            
  144.             // The container in which the component is sited.
  145.             public IContainer Container {
  146.                 get { return container; }
  147.             }
  148.            
  149.             public object GetService(Type service)
  150.             {
  151.                
  152.                 return ((service == typeof(ISite)) ? this : container.GetService(service));
  153.             }
  154.            
  155.             // Indicates whether the component is in design mode.
  156.             public bool DesignMode {
  157.                 get {
  158.                     IComponent owner = container.Owner;
  159.                     if (owner != null && owner.Site != null) {
  160.                         return owner.Site.DesignMode;
  161.                     }
  162.                     return false;
  163.                 }
  164.             }
  165.            
  166.             public string FullName {
  167.                 get {
  168.                     if (name != null) {
  169.                         string ownerName = container.OwnerName;
  170.                         string childName = name;
  171.                         if (ownerName != null) {
  172.                             childName = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", ownerName, childName);
  173.                         }
  174.                        
  175.                         return childName;
  176.                     }
  177.                    
  178.                     return name;
  179.                 }
  180.             }
  181.            
  182.             // The name of the component.
  183.             //
  184.             public string Name {
  185.                 get { return name; }
  186.                 set {
  187.                     if (value == null || name == null || !value.Equals(name)) {
  188.                         container.ValidateName(component, value);
  189.                         name = value;
  190.                     }
  191.                 }
  192.             }
  193.         }
  194.     }
  195. }

Developer Fusion