Applying Property Attributes decorating a class to its member properties  
Author Message
Greg D Clark





PostPosted: Visual C# General, Applying Property Attributes decorating a class to its member properties Top

I am using attributes to supply range values for properties of an object being displayed in a propertyGrid. This works great when I am dealing with primitive types like int and float. However I have more complex data types that I want to decorate with a range attribute and have the attribute applied to member items of the object that was decorated.

It should be noted that I have created custom type and property descriptors so that I have control over those description passed to the property grid. This allows me to control how the property grid displays properties dynamically. To apply the range constraints to the property I have overridden the SetValue Method in the property descriptor. The problem is when you are changing the value to the member of an object (such as memberItem1 in the code below) it does not really have access to the attribute information decorating it's owners instance.

I have tried a few things... trying to forcibly add the attribute to the members when the object is constructed. However I don't know how to get a reference to the 'owner' of the object during construction to read the range attribute.

If anybody knows how to do this, or possibly has a different elegant way of dealing with ranges i'm all ears.

Thanks

Below is code demonstating what hwo I wish to use the attribute.

[ClassSpecificAttribute()]

public class ClassA

{

private int memberItem1; // fields

private int memberItem2;

public int MemberItem1 // property

{

get{...;}

set{...;}

}

public int MemberItem2 // property

{

get{...;}

set{...;}

}

}

public class ContainerClass

{

private int myInteger; // fields

private ClassA instanceOfClassA;

[IRangeAttribute(5,100)] // properties

public int MyInteger

{

get{...;}

set{...;}

}

[IRangeAttribute(0,50)]

public ClassA InstanceOfClassA

{

get {...;}

set {...;}

}

}

class Main

{

private ContainerClass myContainer;

...

propertyGrid1.selectedObject = myContainer;

}



Visual C#2  
 
 
TaylorMichaelL





PostPosted: Visual C# General, Applying Property Attributes decorating a class to its member properties Top

In the framework there are a couple of different options. In your case you are trying to fit "a square in a round hole". I'd recommend that you use the attribute for primitive types only. For complex types you should instead follow a different approach. There are two common techniques that come to mind: interfaces and custom attributes on the type.

The first technique is to use the custom attribute only as an indicator (if needed) that a ranged value exists. Before using the attribute to determine what the range is look at the actual object and see if it implements a custom interface. If the type implements the custom interface then defer to the custom interface for validation.

The second technique is to apply a special attribute to the type that specifies that it uses more complex range checking. When validating the type's value in the grid look for this attribute. If it exists defer to the class to implement the validation. The special attribute would identify yet another class that actually does the validation. This is similar to how type converters and custom editors work.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
public class CustomRangeAttribute : Attribute
{
public CustomRangeAttribute ( Type rangeValidator )
{
}

public Type RangeValidator { get; set; }
}

[CustomRange(typeof(MyClassRangeValidator))]
public class MyClass
{
public int Value1 { get; set; }
public int Value2 { get; set; }
}

public interface ICustomRangeValidator
{
void Validate ( object data, object value );
}

public class MyClassRangeValidator : ICustomRangeValidator
{
public void Validate ( object data, object value )
{
...
}
}

In this case you create a standard interface that all range validators implement. You then expose an attribute to associate an implementation of the interface to a class. The implementation is responsible for validating the data using whatever means it needs. In the property grid whenever you display a property you examine its type for this attribute. If it has one then you use the validator otherwise you check for the custom attribute you already defined. Look in MSDN on how editors and type converters work in .NET for examples of this stuff in action.

Michael Taylor - 11/30/06


 
 
Greg D Clark





PostPosted: Visual C# General, Applying Property Attributes decorating a class to its member properties Top

Thanks Michael..

I'll give this technique a go. I kinda knew I was headed down the wrong path with what I was trying.