This project is read-only.


A Custom Attribute is a user-defined column for a single .tdl ToDoList. Right click a column header and select Add/Edit Custom Columns. The result is a new column in the grid and a new entry field in the edit area. In the .tdl file a node is created under TODOLIST called CUSTOMATTRIB. Each attribute of this node provides a detail as specified during creation. A task that uses one of these will also have a CUSTOMATTRIB node with an ID that matches a header level node and a single Value.

Both the SafeTaskList and the SafeTask support a List<CustomAttribute> called CustomAttributes. There is a method for adding a singular object, AddCustomAttribute. And there are two RemoveCustomAttribute methods, one can be passed a CustomAttribute object and the other can be passed an ID.

A CustomAttribute is a class with the following properties:

  • AttributeType, of type CustomAttributeType
    • A custom attribute definition includes details about the data type as well as whether or not the field is supported by a dropdown list. For this reason both of these concepts are included in this single AttributeType value.
    • This is a struct with just two public properties: ListType and DataType, of types CustomAttributeListType, and CustomAttributeDataType, respectively.
      • CustomAttributeListType is an enum which renders the list type from the TdlAttributeType value (see below) as a strongly-typed value.
      • CustomAttributeDataType is also an enum which defines the data type as String, Date, Integer, etc.
    • When you see the definition of the AttributeType property you'll probably be happy that you don't need to deal with the raw data value.
  • ColumnAlignment, of type ColumnAlignment
    • Simple enum to constrain assignment of Left, Right, and Center alignment. (Apologies to those outside the USA, it's not Centre.)
  • ColumnTitle, string, the text displayed in the column heading
  • Features, of type ColumnFeatures
    • The only non-default feature supported is "Sortable". This enum thus has values None and Sortable.
  • ID, string, a unique reference name for the column
  • Label, string, the text displayed above the edit control
  • TdlAttributeType, string, the internal code direct from the XML
    • When you see this code you'll understand why we have the other classes to support this concept
  • Value, string, only present in tasks

As stated above, a CustomAttribute is found in both the list and the task. The list form has an ID and the other fields, but does not have a Value. The task form only has an ID and a Value.

When a CustomAttribute is added to a SafeTask, the ID is checked to ensure it corresponds to a list-level definition - an exception is thrown if the ID is not found in the list-level collection. There are ways to get around this but this helpful check should be used whenever possible.


More detail for each class can be put here if it seems necessary...


Enum ensures the proper values are inserted into the XML for Left, Center, and Right alignment of a column. (Apologies to non-USA developers who prefer Centre.)


Enum defines available features for a column. Currently only None and Sortable.


Complex class makes use of other class found here. This class represents a custom attribute which is a user-defined field. It displays in the grid with standard columns and causes a control to display in the edit area for maintenance.


Custom attributes may be of type String, Date, Integer, Double, Boolean, and Icon. This enum defines the numeric values which TDL requires in the XML.


Custom attributes can also be configured like other TDL fields, allowing users to select single values or multiple values from lists. This enum allows developers to specify what kind of list is associated with a custom field.


The CustomAttribute.AttributeType field returns this simple struct which is used to detect or set both the List Type and the Data Type of a column. It would seem more elegant to expose these a separate properties, but this structure agrees with the TDL XML which uses byte masking to determine the type of a field.




More to come...

Last edited Feb 17, 2014 at 2:38 AM by TonyGravagno, version 2