Categories
Design Time Support Uncategorized

Enabling Design Time Template Editing

Few days ago, I blogged about how to enable auto formats in the design time smart tag by overriding simple property, this post will describe how to enable design time template editing in a similar simple way.

Template Editing 

[more]

The following steps will show how to do this in your template controls, assuming you already have a template control ( template controls are web server controls that have one or many properties of type ITemplate ).

So, this is how it works :

  1. Implement a custom designer that inherits from System.Web.UI.Design.ControlDesigner
  2. Override the TemplateGroups Collection.
  3. In the get define your template group collection and return it.
  4. Don't forget to enable TemplateEditing flag.

The Sample I introduce here contains a template control having 4 templates which I divide them into 2 template groups.

The SampleControl

[ToolboxData("<{0}:SampleControl runat=server></{0}:SampleControl>")]
[Designer(typeof(SampleControlDesigner))]
public class SampleControl : TemplateControl
{
private ITemplate _firstTemplateX;
 private ITemplate _firstTemplateY;
 private ITemplate _secondTemplateX;
 private ITemplate _secondTemplateY;
}
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate FirstTemplateX
{
 get { return _firstTemplateX; }
 set { _firstTemplateX = value;
}
}
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate FirstTemplateY
{
 get { return _firstTemplateY; }
 set { _firstTemplateY = value; }
}
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate SecondTemplateX
{
 get { return _secondTemplateX; }
 set { _secondTemplateX = value; }
}
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate SecondTemplateY
{
 get { return _secondTemplateY; }
 set { _secondTemplateY = value; }
}
}

The Control Desginer

class SampleControlDesigner : ControlDesigner
{
 public override void Initialize(IComponent component)
 {
base.Initialize(component);
  SetViewFlags(ViewFlags.TemplateEditing, true);
 }
 private TemplateGroupCollection _templateGroups;
 public override TemplateGroupCollection TemplateGroups
 {
  get{
  if (_templateGroups == null)
  {
   _templateGroups = new TemplateGroupCollection();
   TemplateGroup tempGroup1, tempGroup2;
   TemplateDefinition tempDef1, tempDef2, tempDef3, tempDef4;
   SampleControl ctl;
   ctl = (SampleControl)this.Component;
   tempGroup1 = new TemplateGroup("FirstTemplateGroup");
   tempGroup2 = new TemplateGroup("SecondTemplateGroup");
   tempDef1 = new TemplateDefinition(this, "TemplateX", ctl, "FirstTemplateX", true);
   tempDef2 = new TemplateDefinition(this, "TemplateY", ctl, "FirstTemplateY", true);
   tempDef3 = new TemplateDefinition(this, "TemplateX", ctl, "SecondTemplateX", true);
   tempDef4 = new TemplateDefinition(this, "TemplateY", ctl, "SecondTemplateY", true);
   tempGroup1.AddTemplateDefinition(tempDef1);
   tempGroup1.AddTemplateDefinition(tempDef2);
   tempGroup2.AddTemplateDefinition(tempDef3);
   tempGroup2.AddTemplateDefinition(tempDef4);
   _templateGroups.Add(tempGroup1);
   _templateGroups.Add(tempGroup2);
  }
  return _templateGroups;
 }
}
}

The final output of the sample looks like this

Final output of sample

Here's the code so have fun.

SampleControl.cs (3.32 kb)

Categories
Design Time Support Uncategorized

Adding Auto Format for ASP.NET Custom Controls Design Time

Back to design time support, but this time with ASP.NET server controls, most complex & simple controls built in the .NET framework are associated with an Auto Format.. link in the smart tag as the one shown in the figure, I showed in a previous post how to add links and properties to the smart tag of a control.

autoLink  [more]

Ok, now when clicking that link a new window is popped out and you get a list of predefined formats on the left and a preview panel in the right like this.

AutoFormatWindow

Of course if you want to implement these features you will not have to design a new windows form and deal with all the head ache for previewing and those. You only will need some basic steps, I will show next, Assuming you already have your own custom control ( I will just use a simple LabelEx control for this sample);

1- Define your designer.

class LabelExDesigner : ControlDesigner
{

}

2- override the AutoFormats property and return some DesignerAutoFormats, to be used.

private DesignerAutoFormatCollection _autoformats = null;
public override DesignerAutoFormatCollection AutoFormats
{
    get
    {
        if (_autoformats == null)
        {
            _autoformats = new DesignerAutoFormatCollection();
            _autoformats.Add(new LabelExAutoFormat("Remove All"));
            _autoformats.Add(new LabelExAutoFormat("Reddish"));
            _autoformats.Add(new LabelExAutoFormat("Blueish"));
        }
        return _autoformats;
    }
}

3- Define a custom DesignerAutoFormat, which comes with an abstract Apply method, which is called when trying to apply a format on the preview control.

class LabelExAutoFormat : DesignerAutoFormat
{
    public LabelExAutoFormat(string name)
        : base(name)
    { }
    public override void Apply(Control control)
    {
        if (control is LabelEx)
        {
            LabelEx ctrl = control as LabelEx;
            switch (this.Name)
            {
                case "Remove All":
                    ctrl.ControlStyle.Reset();
                    break;
                case "Reddish":
                    ctrl.ControlStyle.ForeColor = ColorTranslator.FromHtml("#ff0000");
                    ctrl.ControlStyle.BackColor = ColorTranslator.FromHtml("#ffccff");
                    ctrl.ControlStyle.Font.Bold = true;
                    break;
                case "Blueish":
                    ctrl.ControlStyle.ForeColor = ColorTranslator.FromHtml("#0000ff");
                    ctrl.ControlStyle.BackColor = ColorTranslator.FromHtml("#99ccff");
                    ctrl.ControlStyle.Font.Italic = true;
                    break;
            }
        }
    }
}

4- And don’t forget to decorate the control with the designer attribute

[Designer(typeof(LabelExDesigner))]
public class LabelEx : Label
{ 
}

And now everything is set and you have your own auto formats.

Default format reddish auto format Blueish auto format

Here is the code and Happy Coding…

Categories
Design Time Support Uncategorized

Custom Controls Design Time Support Part 15: Debugging Design Time

This is final part of my series/tutorial on design time support, it was really fun writing it and hearing your comments and suggestions, I really learnt alot and hope you too had some experience in writing design time support for the custom controls.

In this part, I will show you how to debug the design time code we are writing (works with vs 2005 and 2008).

[more]

Prerequisites:

  1. Have a solution containing the control.
  2. Configuration set to Debug.

Steps:

  1. Open that solution containing the control.
  2. Right click the project and select Properties.
  3. Select Debug Tab as in Figure.
  4. From Select Action Group select Start external program then browse the devenv.exe usually found in this path C:Program FilesMicrosoft Visual Studio 9.0Common7IDEdevenv.exeDebug Tab
  5. Save Settings.
  6. Place breakpoints where ever design time code should be called.
  7. Now Debug the project a new instance of Visual studio will open.
  8. Start a new project to be a container of the project (new web application to test a web control or a windows application for a windows control).
  9. Choose from the toolbox the control you already built ( Right click toolbox > Choose Items > browse for the dll of the control.)
  10. Now drag your control to the testing container and make any design time action (as using smart tag methods), the first instance will stop in breakpoints. Congratulations you are debugging design time code now.

That's the end of the series, but not the end of design time tips and tricks any one comes in my mind, I will be sure to include it in this blog under the category of Design Time Support.

Hope someone out there will benefit from this tutorial, please let me know if you need any help concerning this issue.

Categories
Design Time Support Uncategorized

Custom Controls Design Time Support Part 14: Extra Property Tab

The default PropetryWindow in the visual studio shows 2 Tabs one for properties and another for events. If one day you thought that you have set of members might be Properties that you need to put them in an extra property tab then in this post you will learn how to put extra tabs.

When this can be useful?

After the ajax era has arrived and component authors started to build some ajax controls we usually see Properties named " ClientXXX " where xxx is the event name and these properties just appear in the properties tab while it would be more appropriate to show them in an extra tab say a Client side events.  [more]

How Can you do it?

You need to follow some steps.

  1. Create a Custom Tab that extends the System.Windows.Forms.Design.PropertyTab
  2. override the GetProperties method to send back the selected properties
  3. override the TabName property to set the name of the tab.
  4. override the Bitmap property to set the image of the tab button.
  5. Mark the control/component with PropertyTabAttribute and pass the type of the new Custom Tab.

In code:

[code:c#]

public class ExtraSuperTab : System.Windows.Forms.Design.PropertyTab
{
    public override PropertyDescriptorCollection GetProperties(object component, Attribute[] attributes)
    {
        PropertyDescriptor pd = TypeDescriptor.CreateProperty(component.GetType(), "XXX",typeof(int), new CategoryAttribute("Super Properties"));

        return (new PropertyDescriptorCollection(new PropertyDescriptor[]{pd}));
    }

    public override string TabName
    {
        get { return "Super Tab"; }
    }

    public override System.Drawing.Bitmap Bitmap
    {
        get
        {
            return (System.Drawing.Bitmap)System.Drawing.Image.FromFile(@"D:icon.bmp");
        }
    }
}

[/code]

And in the control don't forget the attribute

[code:c#]

[PropertyTab(typeof(ExtraSuperTab), PropertyTabScope.Component)]
public partial class TestUserControl : UserControl

[/code]

How it looks at the end in visual studio. 

Extra Property Tab 

TestUserControl.cs (1.37 kb)

Categories
Design Time Support Uncategorized

Custom Controls Design Time Support Part 13: Adding Snaplines

Another new feature added in the Design Time Environment in visual studio 2005 and 2008 for windows forms and windows user controls designers is the Snaplines.

What is a snapline?

A snapline is a dynamically generated UI layout guide line. Snaplines are generated during control move operations in the designer. The location of other controls on the design surface provide the lines.

All controls by default inherit the default the Snaplines which appear while moving that interact with Tops, Lefts, Bottoms and Rights of other controls, with the form border, spacings from other controls and some other. One remarkable snapline is the one that appears while moving a Label control beside TextBox controls the purple snapline that aligns the text position instead of the control position. [more]

Now using thr sample control I used in the previous part , I added two labels and two texboxes to simulate a Login control, like the following:

By default when placing this control on a windows form and start moving it around there are no snaplines to interact with the inner labels and textboxes in this sample I will show how to implement custom Snaplines for this usercontrol.

Steps:

1- Add a designer.

2- override Snaplines property and add your own custom ones.

[code:c#]

public override System.Collections.IList SnapLines
{
    get
    {
        IList snaplines = base.SnapLines; //get old snaplines and then add new ones
        snaplines.Add(new SnapLine(SnapLineType.Baseline, _control.lblUserName.Bottom));
        snaplines.Add(new SnapLine(SnapLineType.Baseline, _control.lblPassword.Bottom));
        return snaplines;
    }
}

[/code]

3- Don't forget to add the Designer attribute to the Control definition

[code:c#]

[Designer(typeof(UserControlDesigner))]
public partial class TestUserControl : UserControl

[/code]

The final looks as this.

Final look

So good luck and happy coding with custom controls design time.

UserControlDesigner.cs (7.70 kb)

Categories
Design Time Support Uncategorized

Custom Controls Design Time Support Part 12: Adding SmartTag

One more advantage you get from building a custom designer for your custom controls is that you can add smart tag panel to add important most used properties and methods.

What is a Smart Tag?

aa

SmartTag is one of the new enhancement of VisualStudio 2005 design time and VS 2008 as well. Smart tags are menu-like user interface (UI) elements that supply commonly used design-time options. Most of the standard components and controls provided with the .NET Framework contain smart tag and designer verb enhancements. [more]

Some terminology before we start.

DesignerActionItem :  is a base class for all items on the Action List, a designer action item can be on of the following :

DesignerActionTextItem : Just an item with text does nothing used to give information only without any interaction with the user, can have a display name and a category.

DesignerActionHeaderItem : A special case of text item but written in bold , can have a display name and a category.

DesignerActionProeprtyItem : An item that represents a property, the property that is maps can have an Editor attribute to enhance the editing time (I talked about editors here and here), a property item has a Member Name (the property to me mapped), display name, category and a description (to be shown as a tooltip).

DesignerActionMethodItem : An item that represents a method, the method item has a constructor that accepts the DesignerActionList that the method will be added to, member name, display name, category, description and a boolean value to show this method as a designer verb(I talked about designer verbs here).

DesignerActionList: a collection of Items described above.

DesginerActionListCollection : a collection of Lists of items.

DesignerActionUIService: Manages the UI of the smart tag panel. Used to show, hide and refresh the panel when needed.

How to?

The sample I introduce here depends on the control I created the last two parts.

Add a designer.

Build a custom ActionList by extending the DesignerActionList class.

[code:c#]

public class UserControlDesignerActionList : DesignerActionList
{
     public UserControlDesignerActionList(UserControlDesigner designer)
          : base(designer.Component)
     {
          _designerActionUISvc = GetService(typeof(DesignerActionUIService)) as DesignerActionUIService;
          _controlDesigner = designer;
     }
}

[/code]

Put some properties and methods to be mapped by the action items.

[code:c#]

public Color BorderColor
{
    get
    {
        return _controlDesigner.BorderColor;
    }
    set
    {
        _controlDesigner.BorderColor = value;
        RefreshAll();
    }
}

public bool ShowBorder
{
    get { return _controlDesigner.ShowBorder; }
    set
    {
        _controlDesigner.ShowBorder = value;
        _designerActionUISvc.Refresh(this.Component);
    }
}

public Size Size
{
    get { return _controlDesigner.Control.Size; }
    set { _controlDesigner.Control.Size = value; }
}

public AnchorStyles Anchor
{
    get
    {
        return _controlDesigner.Control.Anchor;
    }
    set
    {
        _controlDesigner.Control.Anchor = value;
    }
}

public void MakeItRed()
{
    _controlDesigner.BorderColor = Color.Red;
    RefreshAll();
}

public void MakeItRandom()
{
    Random r = new Random();
    _controlDesigner.BorderColor = Color.FromArgb(r.Next(256), r.Next(256), r.Next(256));
    RefreshAll();
}

private void RefreshAll()
{
    _controlDesigner.Control.Refresh();
    _designerActionUISvc.Refresh(_controlDesigner.Component);
}

[/code]

And now override the GetSortedItems method a return a customized list.

[code:c#]

public override DesignerActionItemCollection GetSortedActionItems()
{
    DesignerActionItemCollection col = new DesignerActionItemCollection();

    DesignerActionHeaderItem hi = new DesignerActionHeaderItem("Border settings", "Border");
    col.Add(hi);

    DesignerActionPropertyItem pi = new DesignerActionPropertyItem("ShowBorder", "Show the border", "Border", "Check to show the border");
    col.Add(pi);

    if (ShowBorder)
    {
        DesignerActionPropertyItem pi2 = new DesignerActionPropertyItem("BorderColor", "Choose Color", "Border", "Choose a color from editor");
        col.Add(pi2);

        DesignerActionMethodItem mi = new DesignerActionMethodItem(this, "MakeItRed", "Make a Red border", "Border", "Click to change the border to Red", true);
        col.Add(mi);

        DesignerActionMethodItem mi2 = new DesignerActionMethodItem(this, "MakeItRandom", "Random Color", "Border", "Click to get a random border color", true);
        col.Add(mi2);
    }

    DesignerActionHeaderItem hi2 = new DesignerActionHeaderItem("Layout settings", "Layout");
    col.Add(hi2);

    DesignerActionPropertyItem pi3 = new DesignerActionPropertyItem("Size", "Size", "Layout", "Set the Size");
    col.Add(pi3);

    DesignerActionPropertyItem pi4 = new DesignerActionPropertyItem("Anchor", "Anchor", "Layout", "Choose anchor style from editor");
    col.Add(pi4);

    return col;
}

[/code]

Finally, get back to the Designer class and override the ActionLists property and an instance of our custom created ActionList.

[code:c#]

public override DesignerActionListCollection ActionLists
{
     get
     {
         DesignerActionListCollection d = new DesignerActionListCollection();
         d.Add(new UserControlDesignerActionList(this));
         return d;
      }
}

[/code]

And thats it. The final result looks like this.

Final result DesignerActionList

More on this : http://msdn2.microsoft.com/en-us/library/ms171829(VS.80).aspx

Download the sample source code UserControlDesigner.cs (7.16 kb)

Categories
Design Time Support Uncategorized

Custom Controls Design Time Support Part 11: Designer Verbs

This post is simple and neat, the goal now is to add some designer verbs, so lets get straight.

What is a Designer Verb?

A designer can use the DesignerVerb class to add menu commands to the shortcut menu for the component it provides designer support for in design mode. Designer verbs associate a menu item with an event handler. Designer verbs are provided to the design-time environment by the Verbs property of the IDesigner interface. [more]

How to add Designer Verbs?v

I will use the sample I introduced in the last post, I have a TestUserControl that has a red dotted border , and a ShowBorder property to show or hide that border, now I will add on the UserControlDesigner class some verbs ( menu items ) to change the color of the Border ( in case if we had a from with red background so the border will be lost ).

[code:c#]

public override DesignerVerbCollection Verbs
{
    get
    {
        return new DesignerVerbCollection(
            new DesignerVerb[]
            {
                new DesignerVerb("Make Border Red",new EventHandler(MakeRedBorder)),
                new DesignerVerb("Make Border Green",new EventHandler(MakeGreenBorder)),
                new DesignerVerb("Make Border Blue",new EventHandler(MakeBlueBorder)),
            }
            );
    }
}

private void MakeRedBorder(object sender, EventArgs e)
{
    _pen.Color = Color.Red;
    Control.Refresh();
}
private void MakeGreenBorder(object sender, EventArgs e)
{
    _pen.Color = Color.Green;
    Control.Refresh();
}
private void MakeBlueBorder(object sender, EventArgs e)
{
    _pen.Color = Color.Blue;
    Control.Refresh();
}

[/code]

v2Where will they appear?

The verbs will have to places to appear now.

1. In the context menu on the control, on right click.

2. In the Property window when the control is selected, but make sure that the commands is enabled in the property window.

More from msdn: http://msdn2.microsoft.com/en-us/library/xfk1zfw9.aspx

Categories
Design Time Support Uncategorized

Custom Controls Design Time Support Part 10: Filtering Control Members

As I  mentioned in introducing the Designer post that one of the designer powers is filtering the control members, filtering here means removing or adding members (Properties, Events or Attributes) to the DesignTime Environment in the PropertyWindow.

The IDesignerFilter interface has the methods that enable filtering the members that appear in the Design time PropertyWindow. 

The IDesignerFilter interface has 6 methods for filtering.

Why for each Properties , Events and Attributes there is a Pre and Post Filter method?
[more]
From msdn.

If you want to add an attribute or attributes, implement an override of the PreFilterAttributes method that adds the new System..::.Attribute to the IDictionary passed to the method. The keys in the dictionary are the type IDs of the attributes. To change or remove an attribute or attributes, implement an override of the PostFilterAttributes method.

If you want to add an event or events, implement an override of the PreFilterEvents method that adds the new EventDescriptor to the IDictionary passed to the method. The keys in the dictionary are the names of the events. To change or remove an event or events, implement an override of the PostFilterEvents method.

If you want to add a property or properties, implement an override of the PreFilterProperties method that adds the new PropertyDescriptor to the IDictionary passed to the method. The keys in the dictionary are the names of the properties. To change or remove a property or properties, implement an override of the PostFilterProperties method.

Ok now we know why and when we should use these methods, what about a sample. The sample I will introduce here is a designer for a simple UserControl that adds Design Time property to whether show a dotted border or not (to not get lost when not selected) , and will remove some properties too.

[code:c#]

public class UserControlDesigner : ControlDesigner
{
  Pen _pen;
  Control _control;
  bool _showBorder;

  public bool ShowBorder //Property to be added to the Property grid
  {
    get { return _showBorder; }
    set { _showBorder = value; }
  }

  public override void Initialize(System.ComponentModel.IComponent component)
  {
    base.Initialize(component);
    _control = this.Control;v _showBorder = true;
    _pen = new Pen(Color.Red);
    _pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
  }

  protected override void OnPaintAdornments(System.Windows.Forms.PaintEventArgs pe)
  {
    base.OnPaintAdornments(pe);

    if (_showBorder && _control != null)
    {
      pe.Graphics.DrawRectangle(_pen, new Rectangle(0, 0, _control.Width – 1, _control.Height – 1));
    }
  }
}

[/code]

The Above code is for a designer that adds a red dotted border to a control( useful when used with an empty usercontrol ). Now I will add the ShowBorder property to the set of properties associated with the TestUserControl.

[code:c#]

protected override void PreFilterProperties(IDictionary properties)
{
base.PreFilterProperties(properties);

//adding the property here
properties.Add("ShowBorder", TypeDescriptor.CreateProperty(typeof(UserControlDesigner), "ShowBorder", typeof(bool), new DescriptionAttribute("This property only appears in design time."), DesignOnlyAttribute.Yes));
}

[/code]

Just note that I added to the created property some attributes to give it too some design time support, AND don't forget to add the DesignOnlyAttribute.Yes to the attributes array of that property so that it doesn't be serialized and you find a compile time error trying to set that property.

[code:c#]

protected override void PostFilterProperties(IDictionary properties)
{
  properties.Remove("RightToLeft");

  base.PostFilterProperties(properties);
}

[/code]

And here I removed the RightToLeft property. Now all whats left is to associate this designer with the TestUserControl.

[code:c#]

[Designer(typeof(UserControlDesigner))]

public partial class TestUserControl : UserControl

[/code]

Msdn Note:

"When a class extends a designer that implements IDesignerFilter, each PostMethodName method should call the corresponding PostMethodName method of the base class after changing its own attributes, and each PreMethodName method should call the corresponding PreMethodName method of the base class before changing its own attributes."

More on this topic :

Metadata Filtering

Thats all see you next part with Verbs

UserControlDesigner.cs (1.93 kb)

Categories
Design Time Support Uncategorized

Custom Controls Design Time Support Part 9: Introducing the Designer

What is a Designer?

Designers are objects that have the ability to modify a component’s design time behavior on a
design surface. A designer can display a component’s user interface as well as allow property
changes to the component. It can also provide other services and perform additional processing
specific to the component it is associated with. [more]

What is a Designer Capable of?

  1. Filtering Properties in a control.
  2. Add commands in the control context menu during design time.
  3. Adding a smart tag to the control.
  4. much more…

Designer Hierarchy

Desginer Hierarchy

Any .Net designer will have to implement the System.ComponentModel.Design.IDesigner interface, two other Interfaces that extend the IDesigner are the IRootDesigner and the ITreeDesigner.

IRootDesginer : It indicates the root designer. A root designer is simply
a top-level designer for other designers.

Ofcourse windows controls are totally different than web controls, as the first ones paints pixels and the other renders HTML, so the designers too are different. There are 3 main Root Designers, one for Web designer System.Web.UI.Design.WebFormsRootDesigner , one for a Windows designer System.Windows.Forms.Design.DocumentDesigner which is the base for Windows Forms and User Controls, and the last one appears when building other controls System.Windows.Forms.Design.ComponentDocumentDesigner.

ITreeDesigner : Provides support for building a set of related custom designers.

No one will ever need to implement this interface for your Designers, all designers can use the base System.ComponentModel.Design.ComponentDesigner which is the base Designer for all web and all windows designers.

The HtmlControlDesigner is the most suitable base class for any web control designer.

The System.Windows.Forms.Design.ControlDesigner is the most suitable base class for any windows control designer.

As always to attach a Designer to the control you need use an Attribute.

[code:c#]

[Designer(RoundButtonDesigner)]
public class RoundButton : Button

[/code]

So next parts I will show common designer features for both web and windows controls, then show web only and windows only designer features.

Categories
Design Time Support Uncategorized

Custom Controls Design Time Support Part 8: Implementing UITypeEditor

In the previous post I gave a brief introduction on what is a UITypeEditor and what you can get from using it, this part I will show you how to implement one.

So here are the steps:

  1. Define a class that derives from System.Drawing.Design.UITypeEditor.
  2. Override GetEditStyle to return a supported UITypeEditorEditStyle.
  3. Override EditValue and pass any controls necessary to the IWindowsFormsEditorService.
  4. Override GetPaintValueSupported.
  5. Override PaintValue if the editor supports painting.
  6. Override IsDropDownResizable if the editor is resiazble.a


Now we will go through the steps one by one, the example I will introduce here will be another ColorEditor, I will use the ColorWheel introduced and explained in this MSDN magazine article.

The final editor that we will make will look like this

 

[more]

Step 1

[code:c#]

public class ColorWheelEditor : UITypeEditor

[/code]

Step 2

[code:c#]

public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
   return UITypeEditorEditStyle.DropDown;
}

[/code]

Step 3

[code:c#]

public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
   IWindowsFormsEditorService iwefs = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
   Color c;
   using (ColorWheelContainer cwc = new ColorWheelContainer(iwefs))
   {
     cwc.Color = (Color)value;
     iwefs.DropDownControl(cwc);
     if (cwc.Result == DialogResult.OK)
     {
       c = cwc.Color;
     }
     else
     {
       c = (Color)value;
     }
   }
  return c;
}

[/code]

Here, I need to introduce you to the IWindowsFormsEditorService .

Namespace System.Windows.Forms.Design
Assembly System.Windows.Forms
Methods 3
 
DropDownControl accepts a parameter of type control that will be shown the drop down, works when the edit style is UITypeEditorEditStyle.DropDown.
CloseDropDown when called closes the drop down, works when the edit style is UITypeEditorEditStyle.DropDown.
ShowDialog accepts a parameter of type Form, which represents the dialog that will be opened, works when the edit style is UITypeEditorEditStyle.Modal.

Step 4

[code:c#]

public override bool GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context)
{
    return true; // we will use the picked color and fill the rectangle.
}

[/code]

Step 5

[code:c#]

public override void PaintValue(PaintValueEventArgs e)
{
   Color c = (Color)e.Value;
   e.Graphics.FillRectangle(new SolidBrush(c), e.Bounds);
}

[/code]

Step 6

[code:c#]

public override bool IsDropDownResizable
{
   get
   {
     return false;//we don't want it to be resizable
   }
}

[/code]

Now don't forget to associate the editor with the color property using the Editor attribute.

[code:c#]

[Editor(typeof(ColorWheelEditor),typeof(UITypeEditor))]
public Color ColorProperty

[/code]

In this part I showed how to implement a UITypeEditor that appears in a Drop Down. See you soon.

 

ColorWheelEditor.zip (13.99 kb)