Tuesday, December 20, 2005

.Net Design Time Properties for Controls

Ever wanted to add custom properties for your control in .NET. I needed to and found these two classes that can be used to do many different things. UITypeEditor and TypeConverter. The TypeConverter: I had a property that took a string value. By default this property showed up in the designer. But what I wanted to do was constrain the user into selecting from a list of values. To do this I created a typeConvertor similar to the one shown below: 
public class PatternConvertor : TypeConverter {
  static System.ComponentModel.TypeConverter.StandardValuesCollection _svc;
  public PatternConvertor() {
    if (_svc == null) {
      ArrayList values;
      values = new ArrayList();
      values.Add("Value 1");
      values.Add("Value 2");
      _svc = new StandardValuesCollection(values);
    }
  }
  public override bool GetStandardValuesSupported(
      ITypeDescriptorContext context) {
    return true;
  }
  public override System.ComponentModel.TypeConverter.StandardValuesCollection
  GetStandardValues(ITypeDescriptorContext context) {
    return _svc;
  }
}

Next, I had to tell the property to use this Convertor. To do this I added the following attribute: [TypeConverter(typeof(PatternConvertor)) ], to the property

[TypeConverter(typeof(PatternConvertor))]
public string MyValue {
  get { return _value; }
  set { _value = value; }
}

When you click on the control in the designer and view its properties, MyValue will show in the list. MyValue will have a list of values that you can then set. The TypeConvertor class has many more goodies that can be used, such as GetPropertiesSupported, etc. Be sure to check out their functionality. The UITypeEditor: Want to show a custom way of setting a property.... You can do that using a UITypeEditor customized class. In this example I use a trackbar to set a property that takes an integer value. 
public class TrackBarEditor : UITypeEditor {
  public TrackBarEditor() {}
  public override UITypeEditorEditStyle
  GetEditStyle(System.ComponentModel.ITypeDescriptorContext context) {
    return UITypeEditorEditStyle.DropDown;
  }
  public override object EditValue(
      System.ComponentModel.ITypeDescriptorContext context,
      IServiceProvider provider,
      object value) {  // use IWindowsFormsEditorService object to display a
                       // control in the dropdown area
                       // IWindowsFormsEditorService frmsvr =
                       // (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
                       // if(frmsvr == null) return null; TrackBar tbr = new
                       // TrackBar(); tbr.Orientation = Orientation.Vertical;
                       // tbr.Size = new Size(60,120); tbr.TickFrequency = 50;
                       // tbr.SetRange(10,300); frmsvr.DropDownControl(tbr);
                       // return tbr.Value; } }
 Now to use it add the following attribute above the property: 
[Editor(typeof(TrackBarEditor),typeof(UITypeEditor))] 

 Now when you go to the designer, it will drop down a trackbar, which you can slide around to set the value for the property. Cool, huh?! Other useful attributes: RefreshProperties: How should a refresh be performed Description: description shown for the property in the designer Browsable: Should the property show up in the designer DefaultValue: the default value for the property 

Other useful sites for this kind of stuff: Building Windows Forms Controls and Components with Rich Design-Time Features http://msdn.microsoft.com/msdnmag/issues/03/04/Design-TimeControls/default.aspx Building Windows Forms Controls and Components with Rich Design-Time Features, Part 2 http://msdn.microsoft.com/msdnmag/issues/03/05/Design-TimeControls/default.aspx http://www.awprofessional.com/isapi/product_id~%7BB757E215-0FB4-4EA1-A051-65EE537AE9C7%7D/selectDescTypeId~%7B5DBF6018-1234-4204-B35E-903EC67C9A3B%7D/st~%7B5130B593-BAEC-49C6-B6A8-0035DFD1EA3B%7D/content/images/0321116208/samplechapter/sellsch09.pdf

No comments: