2 // System.Windows.Forms.Design.DocumentDesigner
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.
31 using System
.ComponentModel
;
32 using System
.ComponentModel
.Design
;
33 using System
.Windows
.Forms
;
35 using System
.Drawing
.Design
;
36 using System
.Collections
;
38 using System
.Windows
.Forms
.Design
.Behavior
;
41 namespace System
.Windows
.Forms
.Design
44 [ToolboxItemFilter ("System.Windows.Forms")]
46 public class DocumentDesigner
: ScrollableControlDesigner
, IRootDesigner
, IToolboxUser
49 // This is what you *see*
51 .-------------------------------------.
52 | Panel to host the designed Control |
53 |--------------Splitter---------------|
54 | Panel with a ComponentTray |
55 |_____________________________________|
59 #region DesignerViewFrame
60 public class DesignerViewFrame
: System
.Windows
.Forms
.UserControl
62 private System
.Windows
.Forms
.Panel DesignerPanel
;
63 private System
.Windows
.Forms
.Splitter splitter1
;
64 private System
.Windows
.Forms
.Panel ComponentTrayPanel
;
65 private ComponentTray _componentTray
;
66 private Control _designedControl
;
68 public DesignerViewFrame (Control designedControl
, ComponentTray tray
)
70 if (designedControl
== null) {
71 throw new ArgumentNullException ("designedControl");
74 throw new ArgumentNullException ("tray");
77 // The InitializeComponent() call is required for Windows Forms designer support.
79 InitializeComponent();
81 _designedControl
= designedControl
;
82 this.SuspendLayout ();
83 this.DesignerPanel
.Controls
.Add (designedControl
);
86 this.ComponentTray
= tray
;
89 #region Windows Forms Designer generated code
91 /// This method is required for Windows Forms designer support.
92 /// Do not change the method contents inside the source code editor. The Forms designer might
93 /// not be able to load this method if it was changed manually.
95 private void InitializeComponent() {
96 this.ComponentTrayPanel
= new System
.Windows
.Forms
.Panel();
97 this.splitter1
= new System
.Windows
.Forms
.Splitter();
98 this.DesignerPanel
= new System
.Windows
.Forms
.Panel();
101 // ComponentTrayPanel
103 this.ComponentTrayPanel
.BackColor
= System
.Drawing
.Color
.LemonChiffon
;
104 this.ComponentTrayPanel
.Dock
= System
.Windows
.Forms
.DockStyle
.Bottom
;
105 this.ComponentTrayPanel
.Location
= new System
.Drawing
.Point(0, 194);
106 this.ComponentTrayPanel
.Name
= "ComponentTrayPanel";
107 this.ComponentTrayPanel
.Size
= new System
.Drawing
.Size(292, 72);
108 this.ComponentTrayPanel
.TabIndex
= 1;
109 this.ComponentTrayPanel
.Visible
= false;
113 this.splitter1
.Dock
= System
.Windows
.Forms
.DockStyle
.Bottom
;
114 this.splitter1
.Location
= new System
.Drawing
.Point(0, 186);
115 this.splitter1
.Name
= "splitter1";
116 this.splitter1
.Size
= new System
.Drawing
.Size(292, 8);
117 this.splitter1
.TabIndex
= 2;
118 this.splitter1
.TabStop
= false;
119 this.splitter1
.Visible
= false;
123 this.DesignerPanel
.AutoScroll
= true;
124 this.DesignerPanel
.BackColor
= System
.Drawing
.Color
.White
;
125 this.DesignerPanel
.Dock
= System
.Windows
.Forms
.DockStyle
.Fill
;
126 this.DesignerPanel
.Location
= new System
.Drawing
.Point(0, 0);
127 this.DesignerPanel
.Name
= "DesignerPanel";
128 this.DesignerPanel
.Size
= new System
.Drawing
.Size(292, 266);
129 this.DesignerPanel
.TabIndex
= 0;
130 this.DesignerPanel
.MouseUp
+= new System
.Windows
.Forms
.MouseEventHandler(this.DesignerPanel_MouseUp
);
131 this.DesignerPanel
.MouseMove
+= new System
.Windows
.Forms
.MouseEventHandler(this.DesignerPanel_MouseMove
);
132 this.DesignerPanel
.MouseDown
+= new System
.Windows
.Forms
.MouseEventHandler(this.DesignerPanel_MouseDown
);
133 this.DesignerPanel
.Paint
+= new PaintEventHandler (DesignerPanel_Paint
);
137 this.Controls
.Add(this.splitter1
);
138 this.Controls
.Add(this.ComponentTrayPanel
);
139 this.Controls
.Add(this.DesignerPanel
);
140 this.Name
= "UserControl1";
141 this.Size
= new System
.Drawing
.Size(292, 266);
142 this.Dock
= DockStyle
.Fill
;
143 this.ResumeLayout(false);
148 private bool _mouseDown
= false;
149 private bool _firstMove
= false;
151 void DesignerPanel_Paint (object sender
, PaintEventArgs e
)
153 IUISelectionService selectionServ
= this.DesignedControl
.Site
.GetService (typeof (IUISelectionService
)) as IUISelectionService
;
154 if (selectionServ
!= null)
155 selectionServ
.PaintAdornments (this.DesignerPanel
, e
.Graphics
);
158 void DesignerPanel_MouseDown(object sender
, System
.Windows
.Forms
.MouseEventArgs e
)
164 void DesignerPanel_MouseMove(object sender
, System
.Windows
.Forms
.MouseEventArgs e
)
166 IUISelectionService selectionServ
= this.DesignedControl
.Site
.GetService (typeof (IUISelectionService
)) as IUISelectionService
;
167 if (selectionServ
== null)
170 selectionServ
.SetCursor (e
.X
, e
.Y
);
173 selectionServ
.MouseDragBegin (this.DesignerPanel
, e
.X
, e
.Y
);
177 selectionServ
.MouseDragMove (e
.X
, e
.Y
);
180 else if (selectionServ
.SelectionInProgress
) {
181 selectionServ
.MouseDragMove (e
.X
, e
.Y
);
185 void DesignerPanel_MouseUp(object sender
, System
.Windows
.Forms
.MouseEventArgs e
)
187 IUISelectionService selectionServ
= this.DesignedControl
.Site
.GetService (typeof (IUISelectionService
)) as IUISelectionService
;
189 if (selectionServ
!= null)
190 selectionServ
.MouseDragEnd (false);
193 else if (selectionServ
.SelectionInProgress
) {
194 selectionServ
.MouseDragEnd (false);
198 // by default the component tray is hidden and essentially should be shown once there
199 // is a component added to it
201 public void ShowComponentTray ()
203 if (!this.ComponentTray
.Visible
) {
204 this.ComponentTrayPanel
.Visible
= true;
205 this.ComponentTray
.Visible
= true;
206 this.splitter1
.Visible
= true;
210 public void HideComponentTray ()
212 if (!this.ComponentTray
.Visible
) {
213 this.ComponentTrayPanel
.Visible
= true;
214 this.ComponentTray
.Visible
= true;
215 this.splitter1
.Visible
= true;
219 public ComponentTray ComponentTray
{
220 get { return _componentTray; }
222 this.SuspendLayout ();
223 this.ComponentTrayPanel
.Controls
.Remove (_componentTray
);
224 this.ComponentTrayPanel
.Controls
.Add (value);
225 this.ResumeLayout ();
226 _componentTray
= value;
227 _componentTray
.Visible
= false;
231 public Control DesignedControl
{
232 get { return _designedControl; }
237 protected override void Dispose (bool disposing
)
239 if (_designedControl
!= null) {
240 this.DesignerPanel
.Controls
.Remove (_designedControl
);
241 _designedControl
= null;
244 if (_componentTray
!= null) {
245 this.ComponentTrayPanel
.Controls
.Remove (_componentTray
);
246 _componentTray
.Dispose ();
247 _componentTray
= null;
250 base.Dispose (disposing
);
258 private DesignerViewFrame _designerViewFrame
;
260 public DocumentDesigner ()
264 private DesignerViewFrame View
{
265 get { return _designerViewFrame; }
268 #region Initialization
269 public override void Initialize (IComponent component
)
271 base.Initialize (component
);
273 _designerViewFrame
= new DesignerViewFrame (this.Control
, new ComponentTray (this, component
.Site
));
274 _designerViewFrame
.DesignedControl
.Location
= new Point (15, 15);
275 SetValue (this.Component
, "Location", new Point (0, 0));
277 IComponentChangeService componentChangeSvc
= GetService (typeof (IComponentChangeService
)) as IComponentChangeService
;
278 if (componentChangeSvc
!= null) {
279 componentChangeSvc
.ComponentAdded
+= new ComponentEventHandler (OnComponentAdded
);
280 componentChangeSvc
.ComponentRemoved
+= new ComponentEventHandler (OnComponentRemoved
);
283 IMenuCommandService menuCommands
= GetService (typeof (IMenuCommandService
)) as IMenuCommandService
;
284 IServiceContainer serviceContainer
= this.GetService (typeof (IServiceContainer
)) as IServiceContainer
;
285 if (menuCommands
!= null && serviceContainer
!= null)
286 new DefaultMenuCommands (serviceContainer
).AddTo (menuCommands
);
287 InitializeSelectionService ();
290 private void InitializeSelectionService ()
292 IUISelectionService guiSelectionService
= this.GetService (typeof (IUISelectionService
)) as IUISelectionService
;
293 if (guiSelectionService
== null) {
294 IServiceContainer serviceContainer
= this.GetService (typeof (IServiceContainer
)) as IServiceContainer
;
295 serviceContainer
.AddService (typeof (IUISelectionService
), (IUISelectionService
) new UISelectionService (serviceContainer
));
298 ISelectionService selectionService
= this.GetService (typeof (ISelectionService
)) as ISelectionService
;
299 selectionService
.SetSelectedComponents (new IComponent
[] { this.Component }
);
303 // MSDN says overriden
305 public override void OnSetComponentDefaults ()
307 base.OnSetComponentDefaults ();
311 protected override void Dispose (bool disposing
)
314 if (_designerViewFrame
!= null) {
315 _designerViewFrame
.Dispose ();
316 _designerViewFrame
= null;
319 IComponentChangeService componentChangeSvc
= GetService (typeof (IComponentChangeService
)) as IComponentChangeService
;
320 if (componentChangeSvc
!= null) {
321 componentChangeSvc
.ComponentAdded
-= new ComponentEventHandler (OnComponentAdded
);
322 componentChangeSvc
.ComponentRemoved
-= new ComponentEventHandler (OnComponentRemoved
);
325 base.Dispose (disposing
);
330 #region MSDN says overriden
333 public override GlyphCollection
GetGlyphs (GlyphSelectionType selectionType
)
335 return base.GetGlyphs (selectionType
);
339 protected override void WndProc (ref Message m
)
341 base.WndProc (ref m
);
344 protected override void OnContextMenu (int x
, int y
)
346 base.OnContextMenu (x
, y
);
349 protected override void OnCreateHandle ()
351 base.OnCreateHandle ();
357 #region Components and ComponentTray
359 private void OnComponentAdded (object sender
, ComponentEventArgs args
)
361 if (!(args
.Component
is Control
)) {
362 this.View
.ComponentTray
.AddComponent (args
.Component
);
363 if (this.View
.ComponentTray
.ComponentCount
> 0) {
364 if (!this.View
.ComponentTray
.Visible
)
365 this.View
.ShowComponentTray ();
370 private void OnComponentRemoved (object sender
, ComponentEventArgs args
)
372 if (!(args
.Component
is Control
)) {
373 this.View
.ComponentTray
.RemoveComponent (args
.Component
);
374 if (this.View
.ComponentTray
.ComponentCount
== 0) {
375 if (this.View
.ComponentTray
.Visible
)
376 this.View
.HideComponentTray ();
383 #region IRootDesigner
385 object IRootDesigner
.GetView (ViewTechnology technology
)
388 if (technology
!= ViewTechnology
.Default
)
389 throw new ArgumentException ("Only ViewTechnology.WindowsForms is supported.");
391 if (technology
!= ViewTechnology
.WindowsForms
)
392 throw new ArgumentException ("Only ViewTechnology.WindowsForms is supported.");
394 return _designerViewFrame
;
397 ViewTechnology
[] IRootDesigner
.SupportedTechnologies
{
400 return new ViewTechnology
[] { ViewTechnology.Default }
;
402 return new ViewTechnology
[] { ViewTechnology.WindowsForms }
;
411 // Indicates whether the specified tool is supported by the designer.
412 // If it is not the tool is disabled in the toolbox.
414 // Used for subclasses, e.g the FormDocumentDesigner won't accept a Form?
416 bool IToolboxUser
.GetToolSupported (ToolboxItem tool
)
418 return this.GetToolSupported (tool
);
421 protected virtual bool GetToolSupported (ToolboxItem tool
)
427 // Handles the behavior that occurs when a user double-clicks a toolbox item.
429 void IToolboxUser
.ToolPicked (ToolboxItem tool
)
431 this.ToolPicked (tool
);
434 // ToolPicked is called when the user double-clicks on a toolbox item.
435 // The document designer should create a component for the specified tool.
436 // Only tools that are enabled in the toolbox will be passed to this method.
438 // I create the component in the parent container of the primary selection.
439 // If not available I create it in the rootcomponent (this essentially :-) )
441 protected virtual void ToolPicked (ToolboxItem tool
)
443 ISelectionService selectionSvc
= GetService (typeof (ISelectionService
)) as ISelectionService
;
444 IDesignerHost host
= GetService (typeof (IDesignerHost
)) as IDesignerHost
;
445 if (selectionSvc
!= null && host
!= null) {
446 IDesigner designer
= host
.GetDesigner ((IComponent
) selectionSvc
.PrimarySelection
);
447 if (designer
is ParentControlDesigner
)
448 ParentControlDesigner
.InvokeCreateTool ((ParentControlDesigner
) designer
, tool
);
450 this.CreateTool (tool
);
453 this.CreateTool (tool
);
455 IToolboxService tbServ
= this.GetService (typeof (IToolboxService
)) as IToolboxService
;
456 tbServ
.SelectedToolboxItemUsed ();
462 // A root designer can be resized to the bottom and to the right.
464 public override SelectionRules SelectionRules
{
466 return (SelectionRules
.RightSizeable
| SelectionRules
.BottomSizeable
| SelectionRules
.Visible
);
472 #region Metadata filtering and Design-Time properties
474 // MSDN says that this adds the "BackColor" and "Location" browsable design-time propeties.
476 // The reason for overwriting the Location property created by the ControDesigner is that
477 // the root component is not draggable (e.g a form has a static location in the DesignerViewFrame)
479 protected override void PreFilterProperties (IDictionary properties
)
481 base.PreFilterProperties (properties
);
483 PropertyDescriptor propertyDescriptor
= properties
["BackColor"] as PropertyDescriptor
;
484 if (propertyDescriptor
!= null) {
485 properties
["BackColor"] = TypeDescriptor
.CreateProperty (typeof (DocumentDesigner
),
487 new Attribute
[] { new DefaultValueAttribute (System.Drawing.SystemColors.Control) }
);
490 propertyDescriptor
= properties
["Location"] as PropertyDescriptor
;
491 if (propertyDescriptor
!= null) {
492 properties
["Location"] = TypeDescriptor
.CreateProperty (typeof (DocumentDesigner
),
494 new Attribute
[] { new DefaultValueAttribute (typeof (Point), "0, 0") }
);
498 private Color BackColor
{
499 get { return (Color) ShadowProperties["BackColor"]; }
501 ShadowProperties
["BackColor"] = value;
502 this.Control
.BackColor
= value;
506 private Point Location
{
507 get { return (Point) ShadowProperties["Location"]; }
508 set { ShadowProperties["Location"] = value; }
514 protected IMenuEditorService menuEditorService
;
516 // Checks for the existence of a menu editor service and creates one if one does not already exist.
517 // component - The IComponent to ensure has a context menu service.
518 // XXX: Not sure exactly what this should do...
520 protected virtual void EnsureMenuEditorService (IComponent component
)
522 if (this.menuEditorService
== null && component
is ContextMenu
)
523 menuEditorService
= (IMenuEditorService
) GetService (typeof (IMenuEditorService
));