ComponentDesigner.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  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. #if NET_2_0
  34. public class ComponentDesigner : ITreeDesigner, IDesigner, IDisposable, IDesignerFilter, IComponentInitializer
  35. #else
  36. public class ComponentDesigner : IDesigner, IDisposable, IDesignerFilter
  37. #endif
  38. {
  39. #region ShadowPropertyCollection
  40. protected sealed class ShadowPropertyCollection
  41. {
  42. private Hashtable _properties = null;
  43. private IComponent _component;
  44. internal ShadowPropertyCollection (IComponent component)
  45. {
  46. _component = component;
  47. }
  48. // Returns Control's property value (if available) if there is no shadowed one.
  49. //
  50. public object this[string propertyName]
  51. {
  52. get {
  53. if (propertyName == null)
  54. throw new System.ArgumentNullException("propertyName");
  55. if (_properties != null && _properties.ContainsKey (propertyName))
  56. return _properties[propertyName];
  57. PropertyDescriptor property = TypeDescriptor.GetProperties (_component.GetType ())[propertyName];
  58. if (property != null)
  59. return property.GetValue (_component);
  60. else
  61. throw new System.Exception ("Propery not found!");
  62. }
  63. set {
  64. if (_properties == null)
  65. _properties = new Hashtable ();
  66. _properties[propertyName] = value;
  67. }
  68. }
  69. public bool Contains (string propertyName)
  70. {
  71. if (_properties != null)
  72. return _properties.ContainsKey (propertyName);
  73. else
  74. return false;
  75. }
  76. } // ShadowPropertyCollection
  77. #endregion
  78. public ComponentDesigner ()
  79. {
  80. }
  81. private IComponent _component;
  82. private DesignerVerbCollection _verbs;
  83. private ShadowPropertyCollection _shadowPropertyCollection;
  84. #if NET_2_0
  85. private DesignerActionListCollection _designerActionList;
  86. #endif
  87. // This property indicates any components to copy or move along with the component managed
  88. // by the designer during a copy, drag, or move operation.
  89. // If this collection contains references to other components in the current design mode document,
  90. // those components will be copied along with the component managed by the designer during a copy operation.
  91. // When the component managed by the designer is selected, this collection is filled with any nested controls.
  92. // This collection can also include other components, such as the buttons of a toolbar.
  93. //
  94. // supposedly contains all the children of the component, thus used for ITreeDesigner.Children
  95. //
  96. public virtual ICollection AssociatedComponents {
  97. get { return new IComponent[0]; }
  98. }
  99. public IComponent Component {
  100. get { return _component; }
  101. }
  102. public virtual DesignerVerbCollection Verbs {
  103. get {
  104. if (_verbs == null)
  105. _verbs = new DesignerVerbCollection ();
  106. return _verbs;
  107. }
  108. }
  109. protected virtual InheritanceAttribute InheritanceAttribute {
  110. get {
  111. IInheritanceService service = (IInheritanceService) this.GetService (typeof (IInheritanceService));
  112. if (service != null)
  113. return service.GetInheritanceAttribute (_component);
  114. else
  115. return InheritanceAttribute.Default;
  116. }
  117. }
  118. protected bool Inherited {
  119. get { return !this.InheritanceAttribute.Equals (InheritanceAttribute.NotInherited); }
  120. }
  121. //Gets a collection of property values that override user settings.
  122. //
  123. protected ShadowPropertyCollection ShadowProperties {
  124. get {
  125. if (_shadowPropertyCollection == null) {
  126. _shadowPropertyCollection = new ShadowPropertyCollection(_component);
  127. }
  128. return _shadowPropertyCollection;
  129. }
  130. }
  131. #if NET_2_0
  132. public virtual DesignerActionListCollection ActionLists {
  133. get {
  134. if (_designerActionList == null)
  135. _designerActionList = new DesignerActionListCollection ();
  136. return _designerActionList;
  137. }
  138. }
  139. protected virtual IComponent ParentComponent {
  140. get {
  141. IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
  142. if (host != null) {
  143. IComponent rootComponent = host.RootComponent;
  144. if (rootComponent != _component)
  145. return rootComponent;
  146. }
  147. return null;
  148. }
  149. }
  150. public virtual void InitializeNewComponent (IDictionary defaultValues)
  151. {
  152. // Reset
  153. //
  154. OnSetComponentDefaults ();
  155. }
  156. // MSDN: The default implementation of this method does nothing.
  157. //
  158. public virtual void InitializeExistingComponent (IDictionary defaultValues)
  159. {
  160. InitializeNonDefault ();
  161. }
  162. #endif
  163. public virtual void Initialize (IComponent component)
  164. {
  165. if (component == null)
  166. throw new ArgumentNullException ("component");
  167. _component = component;
  168. }
  169. #if NET_2_0
  170. [Obsolete ("This method has been deprecated. Use InitializeExistingComponent instead.")]
  171. #endif
  172. public virtual void InitializeNonDefault ()
  173. {
  174. }
  175. // This method is called when a user double-clicks (the representation of) a component.
  176. // Tries to bind the default event to a method or creates a new one.
  177. //
  178. public virtual void DoDefaultAction()
  179. {
  180. IDesignerHost host = (IDesignerHost) this.GetService(typeof(IDesignerHost));
  181. DesignerTransaction transaction = null;
  182. if (host != null)
  183. transaction = host.CreateTransaction ("ComponentDesigner_AddEvent");
  184. IEventBindingService eventBindingService = GetService (typeof(IEventBindingService)) as IEventBindingService;
  185. EventDescriptor defaultEventDescriptor = null;
  186. if (eventBindingService != null) {
  187. ISelectionService selectionService = this.GetService (typeof (ISelectionService)) as ISelectionService;
  188. try {
  189. if (selectionService != null) {
  190. ICollection selectedComponents = selectionService.GetSelectedComponents ();
  191. foreach (IComponent component in selectedComponents) {
  192. EventDescriptor eventDescriptor = TypeDescriptor.GetDefaultEvent (component);
  193. if (eventDescriptor != null) {
  194. PropertyDescriptor eventProperty = eventBindingService.GetEventProperty (eventDescriptor);
  195. if (eventProperty != null && !eventProperty.IsReadOnly) {
  196. string methodName = eventProperty.GetValue (component) as string;
  197. bool newMethod = true;
  198. if (methodName != null || methodName != String.Empty) {
  199. ICollection compatibleMethods = eventBindingService.GetCompatibleMethods (eventDescriptor);
  200. foreach (string signature in compatibleMethods) {
  201. if (signature == methodName) {
  202. newMethod = false;
  203. break;
  204. }
  205. }
  206. }
  207. if (newMethod) {
  208. if (methodName == null)
  209. methodName = eventBindingService.CreateUniqueMethodName (component, eventDescriptor);
  210. eventProperty.SetValue (component, methodName);
  211. }
  212. if (component == _component)
  213. defaultEventDescriptor = eventDescriptor;
  214. }
  215. }
  216. }
  217. }
  218. }
  219. catch {
  220. if (transaction != null) {
  221. transaction.Cancel ();
  222. transaction = null;
  223. }
  224. }
  225. finally {
  226. if (transaction != null)
  227. transaction.Commit ();
  228. }
  229. if (defaultEventDescriptor != null)
  230. eventBindingService.ShowCode (_component, defaultEventDescriptor);
  231. }
  232. }
  233. #if NET_2_0
  234. [Obsolete ("This method has been deprecated. Use InitializeNewComponent instead.")]
  235. #endif
  236. // The default implementation of this method sets the default property of the component to
  237. // the name of the component if the default property is a string and the property is not already set.
  238. // This method can be implemented in a derived class to customize the initialization of the component
  239. // that this designer is designing.
  240. //
  241. public virtual void OnSetComponentDefaults ()
  242. {
  243. if (_component != null && _component.Site != null) {
  244. PropertyDescriptor property = TypeDescriptor.GetDefaultProperty (_component);
  245. if (property != null && property.PropertyType.Equals (typeof (string))) {
  246. string propertyValue = (string)property.GetValue (_component);
  247. if (propertyValue != null && propertyValue.Length != 0)
  248. property.SetValue (_component, _component.Site.Name);
  249. }
  250. }
  251. }
  252. protected InheritanceAttribute InvokeGetInheritanceAttribute (ComponentDesigner toInvoke)
  253. {
  254. return toInvoke.InheritanceAttribute;
  255. }
  256. #region IDesignerFilter
  257. // TypeDescriptor queries the component's site for ITypeDescriptorFilterService
  258. // then invokes ITypeDescriptorFilterService.XXXX before retrieveing props/event/attributes,
  259. // which then invokes the IDesignerFilter implementation of the component
  260. //
  261. protected virtual void PostFilterAttributes (IDictionary attributes)
  262. {
  263. }
  264. protected virtual void PostFilterEvents (IDictionary events)
  265. {
  266. }
  267. protected virtual void PostFilterProperties (IDictionary properties)
  268. {
  269. }
  270. protected virtual void PreFilterAttributes (IDictionary attributes)
  271. {
  272. }
  273. protected virtual void PreFilterEvents (IDictionary events)
  274. {
  275. }
  276. protected virtual void PreFilterProperties (IDictionary properties)
  277. {
  278. }
  279. #endregion
  280. protected void RaiseComponentChanged (MemberDescriptor member, object oldValue, object newValue)
  281. {
  282. IComponentChangeService service = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
  283. if (service != null)
  284. service.OnComponentChanged (_component, member, oldValue, newValue);
  285. }
  286. protected void RaiseComponentChanging (MemberDescriptor member)
  287. {
  288. IComponentChangeService service = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
  289. if (service != null)
  290. service.OnComponentChanging (_component, member);
  291. }
  292. #region Implementation of IDesignerFilter
  293. void IDesignerFilter.PostFilterAttributes (IDictionary attributes)
  294. {
  295. PostFilterAttributes (attributes);
  296. }
  297. void IDesignerFilter.PostFilterEvents (IDictionary events)
  298. {
  299. PostFilterEvents (events);
  300. }
  301. void IDesignerFilter.PostFilterProperties (IDictionary properties)
  302. {
  303. PostFilterProperties (properties);
  304. }
  305. void IDesignerFilter.PreFilterAttributes (IDictionary attributes)
  306. {
  307. PreFilterAttributes (attributes);
  308. }
  309. void IDesignerFilter.PreFilterEvents (IDictionary events)
  310. {
  311. PreFilterEvents (events);
  312. }
  313. void IDesignerFilter.PreFilterProperties (IDictionary properties)
  314. {
  315. PreFilterProperties (properties);
  316. }
  317. #endregion
  318. #if NET_2_0
  319. #region ITreeDesigner
  320. // Returns a collection of the designers of the associated components
  321. //
  322. ICollection ITreeDesigner.Children {
  323. get {
  324. ICollection components = this.AssociatedComponents;
  325. IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
  326. if (host != null) {
  327. ArrayList designers = new ArrayList ();
  328. foreach (IComponent component in components) {
  329. IDesigner designer = host.GetDesigner (component);
  330. if (designer != null)
  331. designers.Add (designer);
  332. }
  333. IDesigner[] result = new IDesigner[designers.Count];
  334. designers.CopyTo (result);
  335. return result;
  336. }
  337. return new IDesigner[0];
  338. }
  339. }
  340. IDesigner ITreeDesigner.Parent {
  341. get {
  342. IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
  343. if (host != null && this.ParentComponent != null)
  344. return host.GetDesigner (this.ParentComponent);
  345. return null;
  346. }
  347. }
  348. #endregion
  349. #endif
  350. // Helper method - not an ISerivceProvider
  351. //
  352. protected virtual object GetService (Type service)
  353. {
  354. if (_component != null && _component.Site != null)
  355. return _component.Site.GetService (service);
  356. return null;
  357. }
  358. public void Dispose ()
  359. {
  360. this.Dispose (true);
  361. GC.SuppressFinalize (this);
  362. }
  363. protected virtual void Dispose (bool disposing)
  364. {
  365. if (disposing)
  366. _component = null;
  367. }
  368. ~ComponentDesigner ()
  369. {
  370. this.Dispose (false);
  371. }
  372. }
  373. }