Macaw

Macaw

Sunday, April 8, 2007

Hidden features - some things you should know

When you're creating WSS 3.0 Features there are some things you should know:
1. features are cool
2. everyting in WSS is based on a feature
3. ... etc. etc.

I can give you many examples why you should use features, when you're are creating a WSS solution.

One thing I noticed last week, was that if you create a feature with the hidden property set to TRUE. It cannot be an activation dependent feature. So when you activate a feature that is dependent on your new secret hidden feature, it won't work.
The strange thing is, that some of the Microsoft produced features are hidden and do have activation dependencies. Very strange.

WSS 3.0 SPField derrived classes

I've been working with WSS 3.0 for some time now. One of the things I really like is to create my own fieldtypes.
Although the WSS 3.0 SDK has more To Do entries than usable explainations I managed to create my own fieldtypes.
One thing I noticed is that you cannot derrive from the SPFieldLookup. In code you can, but you have to create your own field editor, and there comes the problem. The field editor is the part where you configure the column settings. It's a user control. If you use the normal lookupfieldeditor it won't work, after de-assembling this class I noticed it will always save the field as a SPFieldLookup, and not your custom field.
So I tried to find out, where the lookupfield editor was derrived from. It implements the IFieldEditor. I started working, and coding. And done I was, I thought. It didn't work some of the SPFieldLookup members are made internal; Thank you WSS team.
How did I solve it, I derrived from a different class, the SPFieldMultiChoice field. This worked and now I have my own multi lookup, treeview field.

Below here, some examples, have fun!

My field class derrived from SPFieldMultiChoice:

public class MyLookupField: SPFieldMultiChoice
{
public MyLookupField: (SPFieldCollection fields, string fieldName) : base(fields, fieldName)
{
}

public MyLookupField: (SPFieldCollection fields, string fieldName, string displayName) : base(fields, fieldName, displayName)
{
}

public override void Update()
{
}
}

My field editor class derrived from usercontrol and implemented IFieldEditor (ascx template):

public class MyLookupFieldPropertyEditor: UserControl, IFieldEditor
{
public bool DisplayAsNewSection
{
get { return false; }
}

public void InitializeWithField(SPField field)
{
MyLookupField lookupField = field as MyLookupField;
}

public void OnSaveChange(SPField field, bool isNewField)
{
}

protected override void CreateChildControls()
{
}
}

My lookup field , field control (the field in the edit form) (ascx template):

public class MyLookupFieldControl: BaseFieldControl
{
protected override DefaultTemplateName
{
return "TheNameOfYourAscxTemplate";
}

public override object Value
{
get {}
set
{
SPFieldMultiChoiceValue values = value as SPFieldMultiChoiceValue;
}
}

protected override CreateChildControls()
{
}
}

The xml fieldtypes_*.xml file example
FieldType>
Field Name="TypeName">MyLookupField /Field>
Field Name="TypeDisplayName">My Custom lookup /Field>
Field Name="TypeShortDescription">My Custom lookup fieldtype /Field>
Field Name="ParentType">MultiChoice /Field>
Field Name="UserCreatable">TRUE /Field>
Field Name="FieldTypeClass">My.Assembly.FieldTypes.MyLookupField,My.Asembly,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=223b8b7925bde61b /Field>

Field Name="FieldEditorUserControl">
/_controltemplates/MyLookupFieldPropertyEditor.ascx /Field>
Field Name="Sortable">TRUE /Field>
Field Name="Filterable">TRUE /Field>
/FieldType>
/FieldTypes>

Both ascx template files (just some html) should be placed in the controltemplates directory of the WSS TEMPLATE hive. The assemblies should be placed in the GAC. And a fieldtypes_*.xml should be made to let WSS know you have some other field types.