2 // System.ComponentModel.Design.ComponentDesigner
5 // Ivan N. Zlatev (contact i-nZ.net)
7 // (C) 2006-2007 Ivan N. Zlatev
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections;
33 using System.ComponentModel;
35 namespace System.ComponentModel.Design
39 public class ComponentDesigner : ITreeDesigner, IDesigner, IDisposable, IDesignerFilter, IComponentInitializer
41 public class ComponentDesigner : IDesigner, IDisposable, IDesignerFilter
45 #region ShadowPropertyCollection
47 protected sealed class ShadowPropertyCollection
50 private Hashtable _properties = null;
51 private IComponent _component;
53 internal ShadowPropertyCollection (IComponent component)
55 _component = component;
58 // Returns Control's property value (if available) if there is no shadowed one.
60 public object this[string propertyName]
63 if (propertyName == null)
64 throw new System.ArgumentNullException("propertyName");
66 if (_properties != null && _properties.ContainsKey (propertyName))
67 return _properties[propertyName];
69 PropertyDescriptor property = TypeDescriptor.GetProperties (_component.GetType ())[propertyName];
71 return property.GetValue (_component);
73 throw new System.Exception ("Propery not found!");
76 if (_properties == null)
77 _properties = new Hashtable ();
78 _properties[propertyName] = value;
82 public bool Contains (string propertyName)
84 if (_properties != null)
85 return _properties.ContainsKey (propertyName);
90 } // ShadowPropertyCollection
93 public ComponentDesigner ()
98 private IComponent _component;
99 private DesignerVerbCollection _verbs;
100 private ShadowPropertyCollection _shadowPropertyCollection;
102 private DesignerActionListCollection _designerActionList;
105 // This property indicates any components to copy or move along with the component managed
106 // by the designer during a copy, drag, or move operation.
107 // If this collection contains references to other components in the current design mode document,
108 // those components will be copied along with the component managed by the designer during a copy operation.
109 // When the component managed by the designer is selected, this collection is filled with any nested controls.
110 // This collection can also include other components, such as the buttons of a toolbar.
112 // supposedly contains all the children of the component, thus used for ITreeDesigner.Children
114 public virtual ICollection AssociatedComponents {
115 get { return new IComponent[0]; }
118 public IComponent Component {
119 get { return _component; }
122 public virtual DesignerVerbCollection Verbs {
125 _verbs = new DesignerVerbCollection ();
131 protected virtual InheritanceAttribute InheritanceAttribute {
133 IInheritanceService service = (IInheritanceService) this.GetService (typeof (IInheritanceService));
135 return service.GetInheritanceAttribute (_component);
137 return InheritanceAttribute.Default;
141 protected bool Inherited {
142 get { return !this.InheritanceAttribute.Equals (InheritanceAttribute.NotInherited); }
145 //Gets a collection of property values that override user settings.
147 protected ShadowPropertyCollection ShadowProperties {
149 if (_shadowPropertyCollection == null) {
150 _shadowPropertyCollection = new ShadowPropertyCollection(_component);
152 return _shadowPropertyCollection;
157 public virtual DesignerActionListCollection ActionLists {
159 if (_designerActionList == null)
160 _designerActionList = new DesignerActionListCollection ();
162 return _designerActionList;
166 protected virtual IComponent ParentComponent {
168 IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
170 IComponent rootComponent = host.RootComponent;
171 if (rootComponent != _component)
172 return rootComponent;
178 public virtual void InitializeNewComponent (IDictionary defaultValues)
182 OnSetComponentDefaults ();
185 // MSDN: The default implementation of this method does nothing.
187 public virtual void InitializeExistingComponent (IDictionary defaultValues)
189 InitializeNonDefault ();
194 public virtual void Initialize (IComponent component)
196 if (component == null)
197 throw new ArgumentNullException ("component");
199 _component = component;
203 [Obsolete ("This method has been deprecated. Use InitializeExistingComponent instead.")]
205 public virtual void InitializeNonDefault ()
210 // This method is called when a user double-clicks (the representation of) a component.
211 // Tries to bind the default event to a method or creates a new one.
213 public virtual void DoDefaultAction()
215 IDesignerHost host = (IDesignerHost) this.GetService(typeof(IDesignerHost));
216 DesignerTransaction transaction = null;
218 transaction = host.CreateTransaction ("ComponentDesigner_AddEvent");
220 IEventBindingService eventBindingService = GetService (typeof(IEventBindingService)) as IEventBindingService;
221 EventDescriptor defaultEventDescriptor = null;
223 if (eventBindingService != null) {
224 ISelectionService selectionService = this.GetService (typeof (ISelectionService)) as ISelectionService;
226 if (selectionService != null) {
227 ICollection selectedComponents = selectionService.GetSelectedComponents ();
229 foreach (IComponent component in selectedComponents) {
230 EventDescriptor eventDescriptor = TypeDescriptor.GetDefaultEvent (component);
231 if (eventDescriptor != null) {
232 PropertyDescriptor eventProperty = eventBindingService.GetEventProperty (eventDescriptor);
233 if (eventProperty != null && !eventProperty.IsReadOnly) {
234 string methodName = eventProperty.GetValue (component) as string;
235 bool newMethod = true;
237 if (methodName != null || methodName != String.Empty) {
238 ICollection compatibleMethods = eventBindingService.GetCompatibleMethods (eventDescriptor);
239 foreach (string signature in compatibleMethods) {
240 if (signature == methodName) {
247 if (methodName == null)
248 methodName = eventBindingService.CreateUniqueMethodName (component, eventDescriptor);
250 eventProperty.SetValue (component, methodName);
253 if (component == _component)
254 defaultEventDescriptor = eventDescriptor;
262 if (transaction != null) {
263 transaction.Cancel ();
268 if (transaction != null)
269 transaction.Commit ();
272 if (defaultEventDescriptor != null)
273 eventBindingService.ShowCode (_component, defaultEventDescriptor);
280 [Obsolete ("This method has been deprecated. Use InitializeNewComponent instead.")]
282 // The default implementation of this method sets the default property of the component to
283 // the name of the component if the default property is a string and the property is not already set.
284 // This method can be implemented in a derived class to customize the initialization of the component
285 // that this designer is designing.
287 public virtual void OnSetComponentDefaults ()
289 if (_component != null && _component.Site != null) {
290 PropertyDescriptor property = TypeDescriptor.GetDefaultProperty (_component);
291 if (property != null && property.PropertyType.Equals (typeof (string))) {
292 string propertyValue = (string)property.GetValue (_component);
293 if (propertyValue != null && propertyValue.Length != 0)
294 property.SetValue (_component, _component.Site.Name);
302 protected InheritanceAttribute InvokeGetInheritanceAttribute (ComponentDesigner toInvoke)
304 return toInvoke.InheritanceAttribute;
307 #region IDesignerFilter
309 // TypeDescriptor queries the component's site for ITypeDescriptorFilterService
310 // then invokes ITypeDescriptorFilterService.XXXX before retrieveing props/event/attributes,
311 // which then invokes the IDesignerFilter implementation of the component
313 protected virtual void PostFilterAttributes (IDictionary attributes)
317 protected virtual void PostFilterEvents (IDictionary events)
321 protected virtual void PostFilterProperties (IDictionary properties)
325 protected virtual void PreFilterAttributes (IDictionary attributes)
329 protected virtual void PreFilterEvents (IDictionary events)
333 protected virtual void PreFilterProperties (IDictionary properties)
338 protected void RaiseComponentChanged (MemberDescriptor member, object oldValue, object newValue)
340 IComponentChangeService service = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
342 service.OnComponentChanged (_component, member, oldValue, newValue);
345 protected void RaiseComponentChanging (MemberDescriptor member)
347 IComponentChangeService service = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
349 service.OnComponentChanging (_component, member);
352 #region Implementation of IDesignerFilter
354 void IDesignerFilter.PostFilterAttributes (IDictionary attributes)
356 PostFilterAttributes (attributes);
359 void IDesignerFilter.PostFilterEvents (IDictionary events)
361 PostFilterEvents (events);
364 void IDesignerFilter.PostFilterProperties (IDictionary properties)
366 PostFilterProperties (properties);
369 void IDesignerFilter.PreFilterAttributes (IDictionary attributes)
371 PreFilterAttributes (attributes);
374 void IDesignerFilter.PreFilterEvents (IDictionary events)
376 PreFilterEvents (events);
379 void IDesignerFilter.PreFilterProperties (IDictionary properties)
381 PreFilterProperties (properties);
388 #region ITreeDesigner
389 // Returns a collection of the designers of the associated components
391 ICollection ITreeDesigner.Children {
393 ICollection components = this.AssociatedComponents;
394 IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
397 ArrayList designers = new ArrayList ();
398 foreach (IComponent component in components) {
399 IDesigner designer = host.GetDesigner (component);
400 if (designer != null)
401 designers.Add (designer);
403 IDesigner[] result = new IDesigner[designers.Count];
404 designers.CopyTo (result);
407 return new IDesigner[0];
411 IDesigner ITreeDesigner.Parent {
413 IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
414 if (host != null && this.ParentComponent != null)
415 return host.GetDesigner (this.ParentComponent);
423 // Helper method - not an ISerivceProvider
425 protected virtual object GetService (Type service)
427 if (_component != null && _component.Site != null)
428 return _component.Site.GetService (service);
433 public void Dispose ()
436 GC.SuppressFinalize (this);
440 protected virtual void Dispose (bool disposing)
446 ~ComponentDesigner ()
448 this.Dispose (false);