2008-03-27 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / TableLayoutPanel.cs
1 //
2 // TableLayoutPanel.cs
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 //
23 // Copyright (c) 2006 Jonathan Pobst
24 //
25 // Authors:
26 //      Jonathan Pobst (monkey@jpobst.com)
27 //
28
29 #if NET_2_0
30 using System;
31 using System.Drawing;
32 using System.ComponentModel;
33 using System.Runtime.InteropServices;
34 using System.Windows.Forms.Layout;
35 using System.ComponentModel.Design.Serialization;
36
37 namespace System.Windows.Forms
38 {
39         [ComVisible (true)]
40         [ClassInterface (ClassInterfaceType.AutoDispatch)]
41         [ProvideProperty ("CellPosition", typeof (Control))]
42         [ProvideProperty ("Column", typeof (Control))]
43         [ProvideProperty ("ColumnSpan", typeof (Control))]
44         [ProvideProperty ("Row", typeof (Control))]
45         [ProvideProperty ("RowSpan", typeof (Control))]
46         [DefaultProperty ("ColumnCount")]
47         [Docking (DockingBehavior.Never)]
48         [Designer ("System.Windows.Forms.Design.TableLayoutPanelDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
49         [DesignerSerializer ("System.Windows.Forms.Design.TableLayoutPanelCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
50         public class TableLayoutPanel : Panel, IExtenderProvider
51         {
52                 private TableLayoutSettings settings;
53                 private static TableLayout layout_engine = new TableLayout ();
54                 private TableLayoutPanelCellBorderStyle cell_border_style;
55
56                 // This is the row/column the Control actually got placed
57                 internal Control[,] actual_positions;
58                 
59                 // Widths and heights of each column/row
60                 internal int[] column_widths;
61                 internal int[] row_heights;
62
63                 #region Public Constructor
64                 public TableLayoutPanel ()
65                 {
66                         settings = new TableLayoutSettings(this);
67                         cell_border_style = TableLayoutPanelCellBorderStyle.None;
68                 }
69                 #endregion
70
71                 #region Public Properties
72                 [Localizable (true)]
73                 [Browsable (false)]
74                 [EditorBrowsable (EditorBrowsableState.Never)]
75                 new public BorderStyle BorderStyle {
76                         get { return base.BorderStyle; }
77                         set { base.BorderStyle = value; }
78                 }
79
80                 [Localizable (true)]
81                 [DefaultValue (TableLayoutPanelCellBorderStyle.None)]
82                 public TableLayoutPanelCellBorderStyle CellBorderStyle {
83                         get { return this.cell_border_style; }
84                         set { 
85                                 if (this.cell_border_style != value) {
86                                         this.cell_border_style = value;
87                                         this.PerformLayout (this, "CellBorderStyle");
88                                         this.Invalidate ();
89                                 }
90                         }
91                 }
92
93                 [Localizable (true)]
94                 [DefaultValue (0)]
95                 public int ColumnCount {
96                         get { return settings.ColumnCount; }
97                         set { settings.ColumnCount = value; }
98                 }
99
100                 [Browsable (false)]
101                 [DisplayName ("Columns")]
102                 [MergableProperty (false)]
103                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
104                 public TableLayoutColumnStyleCollection ColumnStyles {
105                         get { return settings.ColumnStyles; }
106                 }
107
108                 [Browsable (false)]
109                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
110                 new public TableLayoutControlCollection Controls {
111                         get { return (TableLayoutControlCollection) base.Controls; }
112                 }
113
114                 [DefaultValue (TableLayoutPanelGrowStyle.AddRows)]
115                 public TableLayoutPanelGrowStyle GrowStyle {
116                         get { return settings.GrowStyle; }
117                         set { settings.GrowStyle = value; }
118                 }
119
120                 public override System.Windows.Forms.Layout.LayoutEngine LayoutEngine {
121                         get { return TableLayoutPanel.layout_engine; }
122                 }
123
124                 [Browsable (false)]
125                 [EditorBrowsable (EditorBrowsableState.Never)]
126                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
127                 public TableLayoutSettings LayoutSettings {
128                         get { return this.settings; }
129                         set {
130                                 if (value.isSerialized) {
131                                         this.settings = value;
132                                         value.isSerialized = false;
133                                 } else
134                                         throw new NotSupportedException ("LayoutSettings value cannot be set directly.");
135                         }
136                 }
137
138                 [Localizable (true)]
139                 [DefaultValue (0)]
140                 public int RowCount {
141                         get { return settings.RowCount; }
142                         set { this.settings.RowCount = value; }
143                 }
144
145                 [Browsable (false)]
146                 [DisplayName ("Rows")]
147                 [MergableProperty (false)]
148                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
149                 public TableLayoutRowStyleCollection RowStyles {
150                         get { return settings.RowStyles; }
151                 }
152                 #endregion
153
154                 #region Public Methods
155                 [DefaultValue (-1)]
156                 [DisplayName ("Cell")]
157                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
158                 public TableLayoutPanelCellPosition GetCellPosition (Control control)
159                 {
160                         return settings.GetCellPosition (control);
161                 }
162
163                 [DisplayName ("Column")]
164                 [DefaultValue (-1)]
165                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
166                 public int GetColumn (Control control)
167                 {
168                         return settings.GetColumn (control);
169                 }
170
171                 [DisplayName ("ColumnSpan")]
172                 [DefaultValue (1)]
173                 public int GetColumnSpan (Control control)
174                 {
175                         return settings.GetColumnSpan (control);
176                 }
177
178                 [Browsable (false)]
179                 [EditorBrowsable (EditorBrowsableState.Never)]
180                 public int[] GetColumnWidths ()
181                 {
182                         return this.column_widths;
183                 }
184
185                 public Control GetControlFromPosition (int column, int row)
186                 {
187                         if (column < 0 || row < 0)
188                                 throw new ArgumentException ();
189
190                         TableLayoutPanelCellPosition pos = new TableLayoutPanelCellPosition (column, row);
191
192                         foreach (Control c in this.Controls)
193                                 if (settings.GetCellPosition (c) == pos)
194                                         return c;
195
196                         return null;
197                 }
198
199                 public TableLayoutPanelCellPosition GetPositionFromControl (Control control)
200                 {
201                         for (int x = 0; x < this.actual_positions.GetLength (0); x++)
202                                 for (int y = 0; y < this.actual_positions.GetLength (1); y++)
203                                         if (this.actual_positions[x, y] == control)
204                                                 return new TableLayoutPanelCellPosition (x, y);
205
206                         return new TableLayoutPanelCellPosition (-1, -1);
207                 }
208
209                 [DisplayName ("Row")]
210                 [DefaultValue ("-1")]
211                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
212                 public int GetRow (Control control)
213                 {
214                         return settings.GetRow (control);
215                 }
216
217                 [Browsable (false)]
218                 [EditorBrowsable (EditorBrowsableState.Never)]
219                 public int[] GetRowHeights ()
220                 {
221                         return this.row_heights;
222                 }
223
224                 [DisplayName ("RowSpan")]
225                 [DefaultValue (1)]
226                 public int GetRowSpan (Control control)
227                 {
228                         return settings.GetRowSpan (control);
229                 }
230
231                 public void SetCellPosition (Control control, TableLayoutPanelCellPosition position)
232                 {
233                         settings.SetCellPosition (control, position);
234                         this.PerformLayout ();
235                 }
236
237                 public void SetColumn (Control control, int column)
238                 {
239                         settings.SetColumn (control, column);
240                         this.PerformLayout ();
241                 }
242
243                 public void SetColumnSpan (Control control, int value)
244                 {
245                         settings.SetColumnSpan (control, value);
246                         this.PerformLayout ();
247                 }
248
249                 public void SetRow (Control control, int row)
250                 {
251                         settings.SetRow (control, row);
252                         this.PerformLayout ();
253                 }
254
255                 public void SetRowSpan (Control control, int value)
256                 {
257                         settings.SetRowSpan (control, value);
258                         this.PerformLayout ();
259                 }
260                 #endregion
261
262                 #region Protected Methods
263                 [EditorBrowsable (EditorBrowsableState.Advanced)]
264                 protected override ControlCollection CreateControlsInstance ()
265                 {
266                         return new TableLayoutControlCollection (this);
267                 }
268
269                 protected virtual void OnCellPaint (TableLayoutCellPaintEventArgs e)
270                 {
271                         TableLayoutCellPaintEventHandler eh = (TableLayoutCellPaintEventHandler)(Events [CellPaintEvent]);
272                         if (eh != null)
273                                 eh (this, e);
274                 }
275
276                 [EditorBrowsable (EditorBrowsableState.Advanced)]
277                 protected override void OnLayout (LayoutEventArgs levent)
278                 {
279                         base.OnLayout (levent);
280                 }
281
282                 protected override void OnPaintBackground (PaintEventArgs e)
283                 {
284                         base.OnPaintBackground (e);
285
286                         if (column_widths == null || row_heights == null)
287                                 return;
288                                 
289                         DrawCellBorders (e);
290                         
291                         int border_width = GetCellBorderWidth (CellBorderStyle);
292
293                         int x = border_width;
294                         int y = border_width;
295                         
296                         for (int i = 0; i < column_widths.Length; i++) {
297                                 for (int j = 0; j < row_heights.Length; j++) {
298                                         this.OnCellPaint (new TableLayoutCellPaintEventArgs (e.Graphics, e.ClipRectangle, new Rectangle (x, y, column_widths[i] + border_width, row_heights[j] + border_width), i, j));
299                                         y += row_heights[j] + border_width;
300                                 }
301
302                                 x += column_widths[i] + border_width;
303                                 y = border_width;
304                         }
305                 }
306
307                 protected override void ScaleControl (SizeF factor, BoundsSpecified specified)
308                 {
309                         base.ScaleControl (factor, specified);
310                 }
311                 
312                 [EditorBrowsable (EditorBrowsableState.Never)]
313                 protected override void ScaleCore (float dx, float dy)
314                 {
315                         base.ScaleCore (dx, dy);
316                 }
317                 #endregion
318
319                 #region Internal Methods
320                 internal static int GetCellBorderWidth (TableLayoutPanelCellBorderStyle style)
321                 {
322                         switch (style) {
323                                 case TableLayoutPanelCellBorderStyle.Single:
324                                         return 1;
325                                 case TableLayoutPanelCellBorderStyle.Inset:
326                                 case TableLayoutPanelCellBorderStyle.Outset:
327                                         return 2;
328                                 case TableLayoutPanelCellBorderStyle.InsetDouble:
329                                 case TableLayoutPanelCellBorderStyle.OutsetPartial:
330                                 case TableLayoutPanelCellBorderStyle.OutsetDouble:
331                                         return 3;
332                         }
333                         
334                         return 0;
335                 }
336                 
337                 private void DrawCellBorders (PaintEventArgs e)
338                 {
339                         Rectangle paint_here = new Rectangle (Point.Empty, this.Size);
340
341                         switch (CellBorderStyle) {
342                                 case TableLayoutPanelCellBorderStyle.Single:
343                                         DrawSingleBorder (e.Graphics, paint_here);
344                                         break;
345                                 case TableLayoutPanelCellBorderStyle.Inset:
346                                         DrawInsetBorder (e.Graphics, paint_here);
347                                         break;
348                                 case TableLayoutPanelCellBorderStyle.InsetDouble:
349                                         DrawInsetDoubleBorder (e.Graphics, paint_here);
350                                         break;
351                                 case TableLayoutPanelCellBorderStyle.Outset:
352                                         DrawOutsetBorder (e.Graphics, paint_here);
353                                         break;
354                                 case TableLayoutPanelCellBorderStyle.OutsetDouble:
355                                 case TableLayoutPanelCellBorderStyle.OutsetPartial:
356                                         DrawOutsetDoubleBorder (e.Graphics, paint_here);
357                                         break;
358                         }
359                 }
360
361                 private void DrawSingleBorder (Graphics g, Rectangle rect)
362                 {
363                         ControlPaint.DrawBorder (g, rect, SystemColors.ControlDark, ButtonBorderStyle.Solid);
364
365                         int x = 0;
366                         int y = 0;
367
368                         for (int i = 0; i < column_widths.Length - 1; i++) {
369                                 x += column_widths[i] + 1;
370
371                                 g.DrawLine (SystemPens.ControlDark, new Point (x, 1), new Point (x, Bottom - 2));
372                         }
373
374                         for (int j = 0; j < row_heights.Length - 1; j++) {
375                                 y += row_heights[j] + 1;
376
377                                 g.DrawLine (SystemPens.ControlDark, new Point (1, y), new Point (Right - 2, y));
378                         }
379                 }
380
381                 private void DrawInsetBorder (Graphics g, Rectangle rect)
382                 {
383                         ControlPaint.DrawBorder3D (g, rect, Border3DStyle.Etched);
384                         
385                         int x = 0;
386                         int y = 0;
387
388                         for (int i = 0; i < column_widths.Length - 1; i++) {
389                                 x += column_widths[i] + 2;
390
391                                 g.DrawLine (SystemPens.ControlDark, new Point (x, 1), new Point (x, Bottom - 3));
392                                 g.DrawLine (Pens.White, new Point (x + 1, 1), new Point (x + 1, Bottom - 3));
393                         }
394
395                         for (int j = 0; j < row_heights.Length - 1; j++) {
396                                 y += row_heights[j] + 2;
397
398                                 g.DrawLine (SystemPens.ControlDark, new Point (1, y), new Point (Right - 3, y));
399                                 g.DrawLine (Pens.White, new Point (1, y + 1), new Point (Right - 3, y + 1));
400                         }
401                 }
402
403                 private void DrawOutsetBorder (Graphics g, Rectangle rect)
404                 {
405                         g.DrawRectangle (SystemPens.ControlDark, new Rectangle (rect.Left + 1, rect.Top + 1, rect.Width - 2, rect.Height - 2));
406                         g.DrawRectangle (Pens.White, new Rectangle (rect.Left, rect.Top, rect.Width - 2, rect.Height - 2));
407
408                         int x = 0;
409                         int y = 0;
410
411                         for (int i = 0; i < column_widths.Length - 1; i++) {
412                                 x += column_widths[i] + 2;
413
414                                 g.DrawLine (Pens.White, new Point (x, 1), new Point (x, Bottom - 3));
415                                 g.DrawLine (SystemPens.ControlDark, new Point (x + 1, 1), new Point (x + 1, Bottom - 3));
416                         }
417
418                         for (int j = 0; j < row_heights.Length - 1; j++) {
419                                 y += row_heights[j] + 2;
420
421                                 g.DrawLine (Pens.White, new Point (1, y), new Point (Right - 3, y));
422                                 g.DrawLine (SystemPens.ControlDark, new Point (1, y + 1), new Point (Right - 3, y + 1));
423                         }
424                 }
425
426                 private void DrawOutsetDoubleBorder (Graphics g, Rectangle rect)
427                 {
428                         rect.Width -= 1;
429                         rect.Height -= 1;
430                         
431                         g.DrawRectangle (SystemPens.ControlDark, new Rectangle (rect.Left + 2, rect.Top + 2, rect.Width - 2, rect.Height - 2));
432                         g.DrawRectangle (Pens.White, new Rectangle (rect.Left, rect.Top, rect.Width - 2, rect.Height - 2));
433
434                         int x = 0;
435                         int y = 0;
436
437                         for (int i = 0; i < column_widths.Length - 1; i++) {
438                                 x += column_widths[i] + 3;
439
440                                 g.DrawLine (Pens.White, new Point (x, 3), new Point (x, Bottom - 5));
441                                 g.DrawLine (SystemPens.ControlDark, new Point (x + 2, 3), new Point (x + 2, Bottom - 5));
442                         }
443
444                         for (int j = 0; j < row_heights.Length - 1; j++) {
445                                 y += row_heights[j] + 3;
446
447                                 g.DrawLine (Pens.White, new Point (3, y), new Point (Right - 4, y));
448                                 g.DrawLine (SystemPens.ControlDark, new Point (3, y + 2), new Point (Right - 4, y + 2));
449                         }
450
451                         x = 0;
452                         y = 0;
453                         
454                         for (int i = 0; i < column_widths.Length - 1; i++) {
455                                 x += column_widths[i] + 3;
456
457                                 g.DrawLine (ThemeEngine.Current.ResPool.GetPen (BackColor), new Point (x + 1, 3), new Point (x + 1, Bottom - 5));
458                         }
459
460                         for (int j = 0; j < row_heights.Length - 1; j++) {
461                                 y += row_heights[j] + 3;
462
463                                 g.DrawLine (ThemeEngine.Current.ResPool.GetPen (BackColor), new Point (3, y + 1), new Point (Right - 4, y + 1));
464                         }
465                 }
466         
467                 private void DrawInsetDoubleBorder (Graphics g, Rectangle rect)
468                 {
469                         rect.Width -= 1;
470                         rect.Height -= 1;
471                         
472                         g.DrawRectangle (Pens.White, new Rectangle (rect.Left + 2, rect.Top + 2, rect.Width - 2, rect.Height - 2));
473                         g.DrawRectangle (SystemPens.ControlDark, new Rectangle (rect.Left, rect.Top, rect.Width - 2, rect.Height - 2));
474
475                         int x = 0;
476                         int y = 0;
477
478                         for (int i = 0; i < column_widths.Length - 1; i++) {
479                                 x += column_widths[i] + 3;
480
481                                 g.DrawLine (SystemPens.ControlDark, new Point (x, 3), new Point (x, Bottom - 5));
482                                 g.DrawLine (Pens.White, new Point (x + 2, 3), new Point (x + 2, Bottom - 5));
483                         }
484
485                         for (int j = 0; j < row_heights.Length - 1; j++) {
486                                 y += row_heights[j] + 3;
487
488                                 g.DrawLine (SystemPens.ControlDark, new Point (3, y), new Point (Right - 4, y));
489                                 g.DrawLine (Pens.White, new Point (3, y + 2), new Point (Right - 4, y + 2));
490                         }
491
492                         x = 0;
493                         y = 0;
494                         
495                         for (int i = 0; i < column_widths.Length - 1; i++) {
496                                 x += column_widths[i] + 3;
497
498                                 g.DrawLine (ThemeEngine.Current.ResPool.GetPen (BackColor), new Point (x + 1, 3), new Point (x + 1, Bottom - 5));
499                         }
500
501                         for (int j = 0; j < row_heights.Length - 1; j++) {
502                                 y += row_heights[j] + 3;
503
504                                 g.DrawLine (ThemeEngine.Current.ResPool.GetPen (BackColor), new Point (3, y + 1), new Point (Right - 4, y + 1));
505                         }
506                 }
507
508                 internal override Size GetPreferredSizeCore (Size proposedSize)
509                 {
510                         // If the tablelayoutpanel is autosize, we have to make sure it is big enough
511                         // to hold every non-autosize control
512                         actual_positions = (LayoutEngine as TableLayout).CalculateControlPositions (this, Math.Max (ColumnCount, 1), Math.Max (RowCount, 1));
513                         
514                         // Figure out how wide the panel needs to be
515                         int[] column_widths = new int[ColumnCount];
516                         float total_column_percentage = 0f;
517                         
518                         // Figure out how tall each column wants to be
519                         for (int i = 0; i < ColumnCount; i++) {
520                                 if (i < ColumnStyles.Count && ColumnStyles[i].SizeType == SizeType.Percent)
521                                         total_column_percentage += ColumnStyles[i].Width;
522                                         
523                                 int biggest = 0;
524
525                                 for (int j = 0; j < RowCount; j++) {
526                                         Control c = actual_positions[i, j];
527
528                                         if (c != null) {
529                                                 if (!c.AutoSize)
530                                                         biggest = Math.Max (biggest, c.ExplicitBounds.Width + c.Margin.Horizontal + Padding.Horizontal);
531                                                 else
532                                                         biggest = Math.Max (biggest, c.ExplicitBounds.Width + c.Margin.Horizontal + Padding.Horizontal);
533                                         }
534                                 }
535
536                                 column_widths[i] = biggest;
537                         }
538
539                         // Because percentage based rows divy up the remaining space,
540                         // we have to make the panel big enough so that all the rows
541                         // get bigger, even if we only need one to be bigger.
542                         int non_percent_total_width = 0;
543                         int percent_total_width = 0;
544
545                         for (int i = 0; i < ColumnCount; i++) {
546                                 if (i < ColumnStyles.Count && ColumnStyles[i].SizeType == SizeType.Percent)
547                                         percent_total_width = Math.Max (percent_total_width, (int)(column_widths[i] / ((ColumnStyles[i].Width) / total_column_percentage)));
548                                 else
549                                         non_percent_total_width += column_widths[i];
550                         }
551
552
553                         // Figure out how tall the panel needs to be
554                         int[] row_heights = new int[RowCount];
555                         float total_row_percentage = 0f;
556                 
557                         // Figure out how tall each row wants to be
558                         for (int j = 0; j < RowCount; j++) {
559                                 if (j < RowStyles.Count && RowStyles[j].SizeType == SizeType.Percent)
560                                         total_row_percentage += RowStyles[j].Height;
561                                         
562                                 int biggest = 0;
563                                 
564                                 for (int i = 0; i < ColumnCount; i++) {
565                                         Control c = actual_positions[i, j];
566
567                                         if (c != null) {
568                                                 if (!c.AutoSize)
569                                                         biggest = Math.Max (biggest, c.ExplicitBounds.Height + c.Margin.Vertical + Padding.Vertical);
570                                                 else
571                                                         biggest = Math.Max (biggest, c.PreferredSize.Height + c.Margin.Vertical + Padding.Vertical);
572                                         }
573                                 }
574
575                                 row_heights[j] = biggest;
576                         }
577                         
578                         // Because percentage based rows divy up the remaining space,
579                         // we have to make the panel big enough so that all the rows
580                         // get bigger, even if we only need one to be bigger.
581                         int non_percent_total_height = 0;
582                         int percent_total_height = 0;
583                         
584                         for (int j = 0; j < RowCount; j++) {
585                                 if (j < RowStyles.Count && RowStyles[j].SizeType == SizeType.Percent)
586                                         percent_total_height = Math.Max (percent_total_height, (int)(row_heights[j] / ((RowStyles[j].Height) / total_row_percentage)));
587                                 else
588                                         non_percent_total_height += row_heights[j];
589                         }
590
591                         return new Size (non_percent_total_width + percent_total_width, non_percent_total_height + percent_total_height);
592                 }
593                 #endregion
594                 
595                 #region Public Events
596                 static object CellPaintEvent = new object ();
597
598                 public event TableLayoutCellPaintEventHandler CellPaint {
599                         add { Events.AddHandler (CellPaintEvent, value); }
600                         remove { Events.RemoveHandler (CellPaintEvent, value); }
601                 }
602                 #endregion
603                 
604                 #region IExtenderProvider
605                 bool IExtenderProvider.CanExtend (object extendee)
606                 {
607                         if (extendee is Control)
608                                 if ((extendee as Control).Parent == this)
609                                         return true;
610
611                         return false;
612                 }
613                 #endregion
614                 
615         }
616 }
617 #endif