PageRenderTime 90ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/System.Design/System.ComponentModel.Design/ComponentDesigner.cs

https://github.com/pruiz/mono
C# | 437 lines | 299 code | 78 blank | 60 comment | 81 complexity | 84f768513b0be419e771769ee8b32b1b MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. //
  2. // System.ComponentModel.Design.ComponentDesigner
  3. //
  4. // Authors:
  5. // Ivan N. Zlatev (contact i-nZ.net)
  6. //
  7. // (C) 2006-2007 Ivan N. Zlatev
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. using System;
  29. using System.Collections;
  30. using System.ComponentModel;
  31. namespace System.ComponentModel.Design
  32. {
  33. public class ComponentDesigner : ITreeDesigner, IDesigner, IDisposable, IDesignerFilter, IComponentInitializer
  34. {
  35. #region ShadowPropertyCollection
  36. protected sealed class ShadowPropertyCollection
  37. {
  38. private Hashtable _properties = null;
  39. private IComponent _component;
  40. internal ShadowPropertyCollection (IComponent component)
  41. {
  42. _component = component;
  43. }
  44. // Returns Control's property value (if available) if there is no shadowed one.
  45. //
  46. public object this[string propertyName]
  47. {
  48. get {
  49. if (propertyName == null)
  50. throw new System.ArgumentNullException("propertyName");
  51. if (_properties != null && _properties.ContainsKey (propertyName))
  52. return _properties[propertyName];
  53. PropertyDescriptor property = TypeDescriptor.GetProperties (_component.GetType ())[propertyName];
  54. if (property != null)
  55. return property.GetValue (_component);
  56. else
  57. throw new System.Exception ("Propery not found!");
  58. }
  59. set {
  60. if (_properties == null)
  61. _properties = new Hashtable ();
  62. _properties[propertyName] = value;
  63. }
  64. }
  65. public bool Contains (string propertyName)
  66. {
  67. if (_properties != null)
  68. return _properties.ContainsKey (propertyName);
  69. else
  70. return false;
  71. }
  72. } // ShadowPropertyCollection
  73. #endregion
  74. public ComponentDesigner ()
  75. {
  76. }
  77. private IComponent _component;
  78. private DesignerVerbCollection _verbs;
  79. private ShadowPropertyCollection _shadowPropertyCollection;
  80. private DesignerActionListCollection _designerActionList;
  81. // This property indicates any components to copy or move along with the component managed
  82. // by the designer during a copy, drag, or move operation.
  83. // If this collection contains references to other components in the current design mode document,
  84. // those components will be copied along with the component managed by the designer during a copy operation.
  85. // When the component managed by the designer is selected, this collection is filled with any nested controls.
  86. // This collection can also include other components, such as the buttons of a toolbar.
  87. //
  88. // supposedly contains all the children of the component, thus used for ITreeDesigner.Children
  89. //
  90. public virtual ICollection AssociatedComponents {
  91. get { return new IComponent[0]; }
  92. }
  93. public IComponent Component {
  94. get { return _component; }
  95. }
  96. public virtual DesignerVerbCollection Verbs {
  97. get {
  98. if (_verbs == null)
  99. _verbs = new DesignerVerbCollection ();
  100. return _verbs;
  101. }
  102. }
  103. protected virtual InheritanceAttribute InheritanceAttribute {
  104. get {
  105. IInheritanceService service = (IInheritanceService) this.GetService (typeof (IInheritanceService));
  106. if (service != null)
  107. return service.GetInheritanceAttribute (_component);
  108. else
  109. return InheritanceAttribute.Default;
  110. }
  111. }
  112. protected bool Inherited {
  113. get { return !this.InheritanceAttribute.Equals (InheritanceAttribute.NotInherited); }
  114. }
  115. //Gets a collection of property values that override user settings.
  116. //
  117. protected ShadowPropertyCollection ShadowProperties {
  118. get {
  119. if (_shadowPropertyCollection == null) {
  120. _shadowPropertyCollection = new ShadowPropertyCollection(_component);
  121. }
  122. return _shadowPropertyCollection;
  123. }
  124. }
  125. public virtual DesignerActionListCollection ActionLists {
  126. get {
  127. if (_designerActionList == null)
  128. _designerActionList = new DesignerActionListCollection ();
  129. return _designerActionList;
  130. }
  131. }
  132. protected virtual IComponent ParentComponent {
  133. get {
  134. IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
  135. if (host != null) {
  136. IComponent rootComponent = host.RootComponent;
  137. if (rootComponent != _component)
  138. return rootComponent;
  139. }
  140. return null;
  141. }
  142. }
  143. public virtual void InitializeNewComponent (IDictionary defaultValues)
  144. {
  145. // Reset
  146. //
  147. OnSetComponentDefaults ();
  148. }
  149. // MSDN: The default implementation of this method does nothing.
  150. //
  151. public virtual void InitializeExistingComponent (IDictionary defaultValues)
  152. {
  153. InitializeNonDefault ();
  154. }
  155. public virtual void Initialize (IComponent component)
  156. {
  157. if (component == null)
  158. throw new ArgumentNullException ("component");
  159. _component = component;
  160. }
  161. [Obsolete ("This method has been deprecated. Use InitializeExistingComponent instead.")]
  162. public virtual void InitializeNonDefault ()
  163. {
  164. }
  165. // This method is called when a user double-clicks (the representation of) a component.
  166. // Tries to bind the default event to a method or creates a new one.
  167. //
  168. public virtual void DoDefaultAction()
  169. {
  170. IDesignerHost host = (IDesignerHost) this.GetService(typeof(IDesignerHost));
  171. DesignerTransaction transaction = null;
  172. if (host != null)
  173. transaction = host.CreateTransaction ("ComponentDesigner_AddEvent");
  174. IEventBindingService eventBindingService = GetService (typeof(IEventBindingService)) as IEventBindingService;
  175. EventDescriptor defaultEventDescriptor = null;
  176. if (eventBindingService != null) {
  177. ISelectionService selectionService = this.GetService (typeof (ISelectionService)) as ISelectionService;
  178. try {
  179. if (selectionService != null) {
  180. ICollection selectedComponents = selectionService.GetSelectedComponents ();
  181. foreach (IComponent component in selectedComponents) {
  182. EventDescriptor eventDescriptor = TypeDescriptor.GetDefaultEvent (component);
  183. if (eventDescriptor != null) {
  184. PropertyDescriptor eventProperty = eventBindingService.GetEventProperty (eventDescriptor);
  185. if (eventProperty != null && !eventProperty.IsReadOnly) {
  186. string methodName = eventProperty.GetValue (component) as string;
  187. bool newMethod = true;
  188. if (methodName != null || methodName != String.Empty) {
  189. ICollection compatibleMethods = eventBindingService.GetCompatibleMethods (eventDescriptor);
  190. foreach (string signature in compatibleMethods) {
  191. if (signature == methodName) {
  192. newMethod = false;
  193. break;
  194. }
  195. }
  196. }
  197. if (newMethod) {
  198. if (methodName == null)
  199. methodName = eventBindingService.CreateUniqueMethodName (component, eventDescriptor);
  200. eventProperty.SetValue (component, methodName);
  201. }
  202. if (component == _component)
  203. defaultEventDescriptor = eventDescriptor;
  204. }
  205. }
  206. }
  207. }
  208. }
  209. catch {
  210. if (transaction != null) {
  211. transaction.Cancel ();
  212. transaction = null;
  213. }
  214. }
  215. finally {
  216. if (transaction != null)
  217. transaction.Commit ();
  218. }
  219. if (defaultEventDescriptor != null)
  220. eventBindingService.ShowCode (_component, defaultEventDescriptor);
  221. }
  222. }
  223. [Obsolete ("This method has been deprecated. Use InitializeNewComponent instead.")]
  224. // The default implementation of this method sets the default property of the component to
  225. // the name of the component if the default property is a string and the property is not already set.
  226. // This method can be implemented in a derived class to customize the initialization of the component
  227. // that this designer is designing.
  228. //
  229. public virtual void OnSetComponentDefaults ()
  230. {
  231. if (_component != null && _component.Site != null) {
  232. PropertyDescriptor property = TypeDescriptor.GetDefaultProperty (_component);
  233. if (property != null && property.PropertyType.Equals (typeof (string))) {
  234. string propertyValue = (string)property.GetValue (_component);
  235. if (propertyValue != null && propertyValue.Length != 0)
  236. property.SetValue (_component, _component.Site.Name);
  237. }
  238. }
  239. }
  240. protected InheritanceAttribute InvokeGetInheritanceAttribute (ComponentDesigner toInvoke)
  241. {
  242. return toInvoke.InheritanceAttribute;
  243. }
  244. #region IDesignerFilter
  245. // TypeDescriptor queries the component's site for ITypeDescriptorFilterService
  246. // then invokes ITypeDescriptorFilterService.XXXX before retrieveing props/event/attributes,
  247. // which then invokes the IDesignerFilter implementation of the component
  248. //
  249. protected virtual void PostFilterAttributes (IDictionary attributes)
  250. {
  251. }
  252. protected virtual void PostFilterEvents (IDictionary events)
  253. {
  254. }
  255. protected virtual void PostFilterProperties (IDictionary properties)
  256. {
  257. }
  258. protected virtual void PreFilterAttributes (IDictionary attributes)
  259. {
  260. }
  261. protected virtual void PreFilterEvents (IDictionary events)
  262. {
  263. }
  264. protected virtual void PreFilterProperties (IDictionary properties)
  265. {
  266. }
  267. #endregion
  268. protected void RaiseComponentChanged (MemberDescriptor member, object oldValue, object newValue)
  269. {
  270. IComponentChangeService service = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
  271. if (service != null)
  272. service.OnComponentChanged (_component, member, oldValue, newValue);
  273. }
  274. protected void RaiseComponentChanging (MemberDescriptor member)
  275. {
  276. IComponentChangeService service = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
  277. if (service != null)
  278. service.OnComponentChanging (_component, member);
  279. }
  280. #region Implementation of IDesignerFilter
  281. void IDesignerFilter.PostFilterAttributes (IDictionary attributes)
  282. {
  283. PostFilterAttributes (attributes);
  284. }
  285. void IDesignerFilter.PostFilterEvents (IDictionary events)
  286. {
  287. PostFilterEvents (events);
  288. }
  289. void IDesignerFilter.PostFilterProperties (IDictionary properties)
  290. {
  291. PostFilterProperties (properties);
  292. }
  293. void IDesignerFilter.PreFilterAttributes (IDictionary attributes)
  294. {
  295. PreFilterAttributes (attributes);
  296. }
  297. void IDesignerFilter.PreFilterEvents (IDictionary events)
  298. {
  299. PreFilterEvents (events);
  300. }
  301. void IDesignerFilter.PreFilterProperties (IDictionary properties)
  302. {
  303. PreFilterProperties (properties);
  304. }
  305. #endregion
  306. #region ITreeDesigner
  307. // Returns a collection of the designers of the associated components
  308. //
  309. ICollection ITreeDesigner.Children {
  310. get {
  311. ICollection components = this.AssociatedComponents;
  312. IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
  313. if (host != null) {
  314. ArrayList designers = new ArrayList ();
  315. foreach (IComponent component in components) {
  316. IDesigner designer = host.GetDesigner (component);
  317. if (designer != null)
  318. designers.Add (designer);
  319. }
  320. IDesigner[] result = new IDesigner[designers.Count];
  321. designers.CopyTo (result);
  322. return result;
  323. }
  324. return new IDesigner[0];
  325. }
  326. }
  327. IDesigner ITreeDesigner.Parent {
  328. get {
  329. IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
  330. if (host != null && this.ParentComponent != null)
  331. return host.GetDesigner (this.ParentComponent);
  332. return null;
  333. }
  334. }
  335. #endregion
  336. // Helper method - not an ISerivceProvider
  337. //
  338. protected virtual object GetService (Type serviceType)
  339. {
  340. if (_component != null && _component.Site != null)
  341. return _component.Site.GetService (serviceType);
  342. return null;
  343. }
  344. public void Dispose ()
  345. {
  346. this.Dispose (true);
  347. GC.SuppressFinalize (this);
  348. }
  349. protected virtual void Dispose (bool disposing)
  350. {
  351. if (disposing)
  352. _component = null;
  353. }
  354. ~ComponentDesigner ()
  355. {
  356. this.Dispose (false);
  357. }
  358. }
  359. }