Properties

function OpenWin(url, w, h) { if(!w) w = 400; if(!h) h = 300; window.open(url, "_new", "width=" + w + ",height=" + h + ",menubar=no,toobar=no,scrollbars=yes", true); }

The .NET designer architecture provides a RAD (Rapid Application Development) style environment for applications development. One of the keys to the RAD environment is the capability to modify the properties of components visually at design-time. The Windows Forms Designer provides a PropertyGrid that allows for modifying control properties and instantly viewing the result of those modifications.

The .NET designer base classes provide extensive support for editing various types of properties, from intrinsic types such as strings and integers to complex objects such as fonts, collections, and images. Because it is impossible to provide a property editor for types yet unknown, the EditorAttribute is used to define the UITypeEditor that the PropertyGrid will use to support modification of the property. Figure 5.6 shows the UITypeEditor for the Nodes collection of the TreeView control.

Figure 5.6. Nodes property UITypeEditor.

figure 5.6. nodes property uitypeeditor.

Although the Nodes property represents a collection, the TreeView control provides an alternative UITypeEditor rather than the standard CollectionEditor generally associated with collection properties.

UITypeEditor

Providing a custom UITypeEditor for a control or component is fairly simple, thanks in part to the existing designer architecture. The UITypeEditor base class provides four virtual methods that can be overridden to provide a custom UITypeEditor for a component. Table 5.15 lists these methods along with descriptions of each method's purpose.

Table 5.15. UITypeEditor Virtual Methods
Method Description
EditValue Invoked by the PropertyGrid to edit the specified property value.
GetEditStyle Specifies the type of editor as DropDown, Modal, or None.
GetPaintValueSupported Returns true if implementing PaintValue method; otherwise, returns false.
PaintValue Invoked to paint a graphical representation of the edit value.

All that is required in order to associate the UITypeEditor with a particular property is the use of the EditorAttribute. The EditorAttribute specifies the type of editor to be used when editing the property at design-time. Figure 5.7 shows the UITypeEditor that will be built for the IconButton's Icon property.

Figure 5.7. IconEditor for the IconButton.

figure 5.7. iconeditor for the iconbutton.

The typical coding convention for Modal style editors is to have the Form class contained within the editor class as a nested class. The drawback to this is that the designer will not allow for visual development of a nested class. When developing the UITypeEditor, you may want to create the Form class as you would any other Form and then, when finished testing, move the Form class into the editor class. This, however, creates a small issue with the resource file, the corresponding file with the resx extension. To preserve the resource information, it is necessary to include the resource file into the project. I suggest the following steps for creating nested Form classes:

  1. Create a new Form class.

  2. When you are finished developing the form, copy the underlying resx file somewhere safe.

  3. Copy the Form class code into the target parent class, in this case the IconEditor class.

  4. Delete the Form class file.

  5. Add the saved resx file to the project as a resource. Adding an existing item and choosing the resx file can do this.

  6. Double-click the resource file in the Solution explorer. This invokes the resource editor.

  7. In the data sheet of the resource editor, modify the value of $this.name entry to be the qualified name of the dialog (see Figure 5.8). In the case of the IconEditorDialog the qualified name is IconEditor.IconEditorDialog.

    Figure 5.8. The resource data sheet.

    figure 5.8. the resource data sheet.

  8. Locate the line of code in the InitializeComponent method of the form where the resource manager is referenced. It is usually the first line. Modify the qualified name so that it matches that of the $this.name value in the resource file. The following snippet shows the line of code to modify:

     System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(IconEditor.IconEditorDialog)); 
  9. You are ready to build the project.

If it seems like a complex set of steps, it is. Unfortunately, the resource file support for VS .NET is not quite up to par with the way it should be in terms of ease of use. In an attempt to simplify the development process, certain tasks such as resource file management have been made overly complex.

Listing 5.2 contains the source for the IconEditor, along with the nested IconEditorDialog class to act as a custom UITypeEditor.

Listing 5.2 IconEditor UITypeEditor Source
   1: using System;   2: using System.Drawing;   3: using System.Drawing.Design;   4: using System.Collections;   5: using System.ComponentModel;   6: using System.Windows.Forms;   7: using System.Windows.Forms.Design;   8:   9:  10: namespace SAMS.ToolKit.Design  11: {  12:  13:     public class IconEditor : System.Drawing.Design.UITypeEditor  14:     {  15:  16:         public override object EditValue(ITypeDescriptorContext context,  17:                                          IServiceProvider provider,  18:                                          object value) {  19:             IconEditorDialog dlg = new IconEditorDialog( );  20:             IWindowsFormsEditorService winFormEditorService =  graphics/ccc.gif(IWindowsFormsEditorService)provider.GetService( typeof( IWindowsFormsEditorService ) );  21:             if( DialogResult.OK == winFormEditorService.ShowDialog(dlg))  22:                 value = dlg.SelectedIcon;  23:  24:             return value;  25:         }  26:  27:   public override UITypeEditorEditStyle GetEditStyle( ITypeDescriptorContext context  graphics/ccc.gif) {  28:             return UITypeEditorEditStyle.Modal;  29:         }  30:  31:         public override bool GetPaintValueSupported( ITypeDescriptorContext context)  graphics/ccc.gif{  32:             return true;  33:         }  34:  35:         public override void PaintValue( System.Drawing.Design.PaintValueEventArgs  graphics/ccc.gife) {  36:             if( !(e.Value is Icon) )  37:                 return;  38:             Image img = ((Icon)e.Value).ToBitmap( );  39:             Rectangle rcBounds = e.Bounds;  40:             rcBounds.Inflate(-1,-1);  41:             Pen p = System.Drawing.SystemPens.WindowFrame;  42:             e.Graphics.DrawRectangle(p, rcBounds );  43:             if( img != null )  44:                 e.Graphics.DrawImage( img, e.Bounds );  45:         }  46:  47:  48:       protected class IconEditorDialog : System.Windows.Forms.Form  49:         {  50:            private System.Windows.Forms.PictureBox iconPreviewPictureBox;  51:            private System.Windows.Forms.Button btnOpen;  52:            private System.Windows.Forms.Button btnOK;  53:            private System.Windows.Forms.Button btnCancel;  54:            private System.Windows.Forms.PictureBox samsImagePictureBox;  55:            private System.Windows.Forms.OpenFileDialog openFileDialog;  56:  57:            private System.ComponentModel.Container components = null;  58:  59:             private System.Drawing.Icon    selectedIcon;  60:  61:             public Icon SelectedIcon  62:             {  63:                 get {  return selectedIcon; }  64:                 set  65:                 {  66:                     selectedIcon = value;  67:                     iconPreviewPictureBox.Image = ( selectedIcon != null ?  graphics/ccc.gifselectedIcon.ToBitmap( ) : null );  68:                 }  69:     }  70:  71:  72:             public IconEditorDialog()  73:             {  74:                 InitializeComponent();  75:             }  76:  77:             /// <summary>  78:             /// Clean up any resources being used.  79:             /// </summary>  80:             protected override void Dispose( bool disposing )  81:             {  82:                 if( disposing )  83:                 {  84:                     if (components != null)  85:                     {  86:                         components.Dispose();  87:                     }  88:                 }  89:         base.Dispose( disposing );  90:             }  91:  92:             private void InitializeComponent()  93:             {  94:                 System.Resources.ResourceManager resources = new  graphics/ccc.gifSystem.Resources.ResourceManager(typeof(IconEditor.IconEditorDialog));  95:                 this.openFileDialog = new System.Windows.Forms.OpenFileDialog();  96:                 this.btnCancel = new System.Windows.Forms.Button();  97:                 this.iconPreviewPictureBox = new System.Windows.Forms.PictureBox();  98:                 this.btnOpen = new System.Windows.Forms.Button();  99:                 this.samsImagePictureBox = new System.Windows.Forms.PictureBox(); 100:                 this.btnOK = new System.Windows.Forms.Button(); 101:                 this.SuspendLayout(); 102:                 // 103:                 // openFileDialog 104:                 // 105:                 this.openFileDialog.Filter = "Icon Files | *.ico"; 106:                 // 107:                 // btnCancel 108:                 // 109:                 this.btnCancel.Location = new System.Drawing.Point(120, 88); 110:                 this.btnCancel.Name = "btnCancel"; 111:                 this.btnCancel.Size = new System.Drawing.Size(88, 24); 112:      this.btnCancel.TabIndex = 2; 113:                 this.btnCancel.Text = "Cancel"; 114:                 this.btnCancel.Click += new  graphics/ccc.gifSystem.EventHandler(this.btnCancel_Click); 115:                 // 116:                 // iconPreviewPictureBox 117:                 // 118:                 this.iconPreviewPictureBox.BorderStyle =  graphics/ccc.gifSystem.Windows.Forms.BorderStyle.Fixed3D; 119:                 this.iconPreviewPictureBox.Location = new System.Drawing.Point(8, 8); 120:               this.iconPreviewPictureBox.Name = "iconPreviewPictureBox"; 121:                 this.iconPreviewPictureBox.Size = new System.Drawing.Size(100, 68); 122:                 this.iconPreviewPictureBox.SizeMode =  graphics/ccc.gifSystem.Windows.Forms.PictureBoxSizeMode.CenterImage; 123:                 this.iconPreviewPictureBox.TabIndex = 1; 124:                 this.iconPreviewPictureBox.TabStop = false; 125:                 // 126:         // btnOpen 127:                 // 128:                 this.btnOpen.Location = new System.Drawing.Point(120, 8); 129:                 this.btnOpen.Name = "btnOpen"; 130:                 this.btnOpen.Size = new System.Drawing.Size(88, 24); 131:                 this.btnOpen.TabIndex = 2; 132:                 this.btnOpen.Text = "Open..."; 133:       this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click); 134:                 // 135:                 // samsImagePictureBox 136:                 // 137:                 this.samsImagePictureBox.Image =  graphics/ccc.gif((System.Drawing.Bitmap)(resources.GetObject( "samsImagePictureBox.Image"))); 138:                 this.samsImagePictureBox.Location = new System.Drawing.Point(8, 88); 139:                 this.samsImagePictureBox.Name = "samsImagePictureBox"; 140:                 this.samsImagePictureBox.Size = new System.Drawing.Size(96, 32); 141:                 this.samsImagePictureBox.SizeMode =  graphics/ccc.gifSystem.Windows.Forms.PictureBoxSizeMode.CenterImage; 142:                 this.samsImagePictureBox.TabIndex = 3; 143:                 this.samsImagePictureBox.TabStop = false; 144:                 // 145:                 // btnOK 146:                 // 147:                 this.btnOK.Location = new System.Drawing.Point(120, 48); 148:                 this.btnOK.Name = "btnOK"; 149:                 this.btnOK.Size = new System.Drawing.Size(88, 24); 150:                 this.btnOK.TabIndex = 2; 151:                 this.btnOK.Text = "OK"; 152:                 this.btnOK.Click += new System.EventHandler(this.btnOK_Click); 153:                 // 154:                 // IconEditorDialog 155:         // 156:                 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); 157:                 this.ClientSize = new System.Drawing.Size(228, 129); 158:               this.Controls.AddRange(new System.Windows.Forms.Control[]{ 159:                                                this.samsImagePictureBox, 160:                                                this.btnCancel, 161:                                                this.btnOK, 162:                                               this.btnOpen, 163:                                          this.iconPreviewPictureBox} ); 164:                 this.FormBorderStyle =  graphics/ccc.gifSystem.Windows.Forms.FormBorderStyle.FixedDialog; 165:                 this.Name = "IconEditorDialog"; 166:                 this.Text = "IconButton UITypeEditor"; 167:                 this.ResumeLayout(false); 168: 169:             } 170: 171:             private void btnOpen_Click(object sender, System.EventArgs e) 172:             { 173:                 if( DialogResult.OK == openFileDialog.ShowDialog( ) )  { 174:                     try  { 175:                         selectedIcon = new Icon( openFileDialog.FileName ); 176:                     }  catch( Exception exception ) { 177:                         MessageBox.Show( this, exception.Message ); 178:                     }  finally { 179:                         iconPreviewPictureBox.Image = ( selectedIcon != null ?  graphics/ccc.gifselectedIcon.ToBitmap( ) : null ); 180:                     } 181:                 } 182:             } 183: 184:             private void btnOK_Click(object sender, System.EventArgs e) 185:             { 186:                 DialogResult = DialogResult.OK; 187:                 Close( ); 188:             } 189: 190:          private void btnCancel_Click(object sender, System.EventArgs e) 191:         { 192:              DialogResult = DialogResult.Cancel; 193:              Close( ); 194:         } 195:         } 196:  } 197: } 

The code in Listing 5.2 consists of two major components: the dialog for selecting and previewing the icon image, and the code necessary to paint the icon image within the PropertyGrid.

The nested IconEditorDialog is a basic Form-derived class that is used to display an OpenFileDialog for selecting an icon. In addition, the IconEditDialog creates an instance of an IconButton to allow for a simple preview mechanism. After an icon is selected, the IconEditDialog is closed and the IconEditor class is responsible for providing the necessary code to update the PropertyGrid.

The IconEditor class provides the implementation necessary to interact with the PropertyGrid. The first task is to return the type of editor that will be provided. For the IconEditor, the type of Modal is returned, as a nested Form will be used. Other types are DropDown and None. When the EditValue method is invoked, the IconEditor creates and displays the nested IconEditorDialog to allow for the selection of an icon image. When the value of the icon is modified, the PropertyGrid will invoke the GetPaintValueSupported method to determine whether the editor will handle displaying some representation of the property within the PropertyGrid.

Next, the PaintValue method is invoked if the GetPaintValueSupported method returns true. The PaintValue method is responsible for painting within the PropertyGrid for the associated property. The IconEditor renders a miniature image of the icon within0 the PropertyGrid.

To associate the IconEditor with the Icon property, modify the IconButton source and add the EditorAttribute to the Icon property as shown in Listing 5.3.

Listing 5.3 Applying the EditorAttribute
 1: [ 2: System.ComponentModel.Description("The Icon to be displayed in the button"), 3: System.ComponentModel.Category( "Appearance" ), 4: System.ComponentModel.DefaultValue( null ), 5: System.ComponentModel.Editor( typeof( SAMS.ToolKit.Design.IconEditor ), typeof(  graphics/ccc.gifSystem.Drawing.Design.UITypeEditor ) ) 6: ] 7: public Icon Icon {  /* omitted */ } 


    .NET Windows Forms Custom Controls
    User Interfaces in VB .NET: Windows Forms and Custom Controls
    ISBN: 1590590449
    EAN: 2147483647
    Year: 2002
    Pages: 74

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net