Archive for 2005

The easiest way to explain the addition of smart tag functionality to a control or component is to walk through a simple example. I have deliberately kept the example as simple as possible in order to make it quick and easy to see what is required from the additional code you need to write.

Step 1 – Create a new UserControl class

Create a new project and add a new UserControl class to your project. In our example we will add the smart tag to a UserControl but in practice you could add it to any of your existing controls or components.

Drag a new instance of the control onto your Form and then select it. This will result in something even less exciting than this picture of the selected control on the Form.

I customized my control by changing the background color, asking for a border to be drawn and then painting a string in the client area. The full code for the example generated from these steps is available from a link at the end of the article, so there is no need to type in the code from each step.

Step 2 – Add the designer attribute

We need to provide a customized designer for the control in order to provide the information the design time environment needs for showing the smart tag. In order to associate a designer class with the control class we add the following attribute to the control class definition.

[Designer(typeof(UserControl1Designer))]
public class UserControl1 : UserControl

Step 3 – Implement the designer class

The default designer associated with a UserControl is called ControlDesigner and so our custom designer class derives from this. Extending the designer involves overriding just a single property of the base class called ActionLists. This is used to return to the caller a collection of lists that are used to populate the smart tag window.

The default implementation from the ControlDesigner returns an empty collection, hence the absence of the smart tag button when you select the control at design time. Our implementation creates an action list and adds it to the list collection. Here is the complete code for the class.

public class UserControl1Designer : ControlDesigner
{
  public override
             DesignerActionListCollection ActionLists
  {
    get
    {
      DesignerActionListCollection actionLists =
          new DesignerActionListCollection();

      actionLists.Add(
          new UserControl1ActionList(this));

      return actionLists;
    }
  }
}

Step 4 – Implement an action list

This is the class that performs the real work. All action lists must derive from the DesignerActionList base class. We provide a constructor that takes a reference to the designer instance and used it to cache a reference to the control instance.

public class UserControl1ActionList
    : DesignerActionList
{
  private UserControl1 _control;

  public UserControl1ActionList(
      UserControl1Designer owner)
    : base(owner.Component)
  {
    _control = (UserControl1)owner.Component;
  }


Our simple example is going to expose a BackColor entry on the smart tag window that alters the property with the same name on the UserControl1 instance. Whenever you provide a property action you need to implement the property on the action list class itself. Our implementation of the BackColor just calls onto the underlying UserControl1 instance that was cached in the constructor.

  public Color BackColor
  {
    get { return _control.BackColor; }
    set { _control.BackColor = value; }
  }


Our last task is to override the GetSortedActionItems method. This is the method that returns a collection of items that are required to be displayed on the smart tag window. In our case we need to add just a single entry for the BackColor.

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

    actions.Add(new DesignerActionPropertyItem(
                      "BackColor",
                      "BackColor",
                      "Appearance",
                      "Background color."));

    return actions;
  }
}

Step 5 – Compile and open in design mode

Once you have compiled the above code you should be able to select an instance of the UserControl1 control at design time and then access the defined smart tag. You can see it here in it’s full glory!

You can download the source code for this sample from here.

Developing as a lone wolf has some great advantages. Writing all the code yourself ensures that everything is written in a consistent manner and towards your own vision. No more compromises to fit in with a team leader or technical architect’s idea of how things should work.

My experience so far also indicates that you tend to write a higher quality of code. When you know that your income will depend on the quality of what you create it concentrates the mind wonderfully. Instead of being happy to produce good code, now the only benchmark that makes me happy is great code. It has to be just right.

Of course, what is considered good or great is subjective. My great code might be only average from your point of view and visa versa. But the important point is that you are writing code at the limit of your ability and would be happy to be judged by it.

The down side to being a lone developer is that you have no one to turn to when you get stuck. If you have a tricky decision to make there is no one to bounce ideas off, no alternative point of view to attack a problem with. But there is a solution of sorts.

I have just enrolled on the Microsoft ISV Buddy program. This is a scheme from Microsoft that pairs you up with a developer inside Microsoft, giving you a direct line to an internal developer. Even if they cannot answer the problem themselves, they probably know someone else who can.

If your developing for .NET and working either on your own or in an ISV then I recommend you give it a try. Here is the link…

http://msdn.microsoft.com/isv/isvbuddy/default.aspx

Although my blog has been very quite for the last couple of weeks, I have still been hard at work. Just completed this weekend is the Krypton SplitContainer control. This is the Krypton version of the SplitContainer control that comes with the soon to be released Visual Studio 2005.

The intention is not to provide different functionality from the standard SplitContainer but to provide a version that works within the Krypton framework. So it uses the correct appearance as defined by the palette and renderer from the Krypton Toolkit.

This is how it looks at design time with the default Professional palette and renderer.

The container has two panels separated by the position of the splitter. When the panels have no child controls on their surface they show the name of the panel in the centre. Once the user places a control on the panel surface the name watermark is removed.

If you have not used any of the Visual Studio 2005 beta versions then you will not yet be aware of some of the great new changes that are coming up. One of my favorites is the smart tag.

When you select the control at design time it shows the following appearance.

As you would expect, you get a focus rectangle around the control with resizing handles along the edges. If you look at the top left there is a small box that is used to drag the control to a different screen location. This is much easier to use than the old method of dragging the focus rectangle.

At the top right is a little arrow button, this is called the smart tag. When you click this arrow button it shows a popup window with options that can be used to quickly change aspects of the control.

This is a quick way to perform changes to the control without having to navigate to the Properties window and search for the property of interest.

Here is the smart tag display when you press the button for the Krypton SplitContainer control.

So now if you want to alter the splitter from being a vertical to a horizontal split, you just click the smart tag button and press the appropriate command as shown in the picture above.

I have gone ahead and added appropriate smart tags definitions for each of the Krypton controls. It is tempting to add a long list of options but I have restrained myself to just a small set of the obviously useful ones.

I expect smart tags to speed up the time it takes developers to quickly customize controls and also to make it easy for them to discover functionality when first using them.

After a couple of change iterations we seem to be homing in on the best design that our RentACoder company can manage. It has been a real struggle getting them to make the changes I want and push them in the right direction.

I am still not very happy with the ideas they have produced and maybe that is the risk of using a cheap company. You get what you pay for.

Judge for yourself. Here they are….

At last I have managed to get the blogging part of the website up and working. This was actually much easier than I anticipated and largely because of using PHP.

I purchased for just $50 a PHP news/blogging package that adds the full capability to my website. It only took about 30 lines of PHP added to the blogging webpage and it was all up and working. It even includes a nice little html editor for adding new posts and users can add their own comments.

Now I could have tried to do the same thing with ASP.NET but I can just imagine the time it would have taken. I am all in favour of ‘eat your own dog food’ but my microISV is intended to create windows forms controls and not web technology. So I think I made the right choice in going for the quick and cheap option.

Of course, the rest of the site looks a little barren as there is no other content apart from the blogging posts. But one step at a time!