Custom Property Attributes

This is an example of creating a custom attribute that decorates a class attribute.

ColumnWidthAttribute Definition

/// <summary>
/// Used to specify the number of cells wide the field is.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ColumnWidthAttribute : Attribute
{
    /// <summary>
    /// Number of cells in width.
    /// </summary>
    public int TotalColumns { get; private set; }

    /// <summary>
    /// Parameterless ctor defaults to 1 column.
    /// </summary>
    public ColumnWidthAttribute()
        : this(1)
    { }

    /// <summary>
    /// Allow user to specific more than one column.
    /// </summary>
    /// <param name="totalColumns"></param>
    public ColumnWidthAttribute(int totalColumns)
    {
        TotalColumns = totalColumns;
    }
}

Example as property decorator.

public class PostedTransactionHeaderDto
{
    [DisplayName("Payee")]
    [ColumnWidth(2)]
    public string Payee { get; set; }

    [DisplayName("Trust Account Name")]
    [ColumnWidth(3)]
    public string TrustAccountName { get; set; }
}

Retrieve Value at Runtime

Get the attibute value:

// _header is an instance of type PostedTransactionHeaderDto. "Payee" is the property name.
int width = GetColumnWidth(_header.GetType(), "Payee");

Method to query property attribute:

/// <summary>
/// Get ColumnWidth attribute value associated with named parameter. If not present, return 1.
/// </summary>
/// <param name="classInstance">Class object we want to query.</param>
/// <param name="propertyName">Class property name.</param>
/// <returns></returns>
public int GetColumnWidth(Type classInstance, string propertyName)
{
    // Get the property.
    PropertyInfo prop = classInstance.GetProperties().Where(t => t.Name == propertyName).FirstOrDefault();

    // Get attribute and if present, get the total columns value.
    ColumnWidthAttribute attr = (ColumnWidthAttribute)prop
        .GetCustomAttributes(false)
        .Where(t => t.GetType() == typeof(ColumnWidthAttribute))
        .FirstOrDefault();

    // If attribute exists, return embedded value.
    if (!(attr is null))
    {
        return attr.TotalColumns;
    }

    // Attribute not found. Return default value.
    return 1;
}