|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis article was inspired by attempting to improve the code of a user control that was posted here on Code Project. The control had a property that took a series of integers. The way the author handled this was, to put it politely, - a messy hack - so I set out to attempt to improve it as I loved the idea of the control itself. Unfortunately, as it turns out, Microsoft has not made this a very easy process, and I found documentation / online resources in relation to this to be scarce. Viewing some of the .NET source and studying the source of several other articles, I finally managed to get it working fully, so I thought I'd share what I've found. What is a complex property?A complex property is one that has multiple values. A good example of this is the Size3D
The basics (beginner stuff)The starting point is to make three member variables... private int m_Width;
private int m_Height;
private int m_Depth;
... and three corresponding properties. public int Width
{
get { return m_Width; }
set { m_Width = ValidateValue(value); }
}
public int Height
{
get { return m_Height; }
set { m_Height = ValidateValue(value); }
}
public int Depth
{
get { return m_Depth; }
set { m_Depth = ValidateValue(value); }
}
As you can see, each of the setters calls a public const int FieldMinValue = 1;
public const int FieldMaxValue = 255;
I restricted the The next step is to create a simple constructor that takes three public Size3D(int width, int height, int depth)
{
m_Width = ValidateValue(width);
m_Height = ValidateValue(height);
m_Depth = ValidateValue(depth);
}
... and a static 'Empty' public static readonly Size3D Empty = new Size3D();
Next steps (slightly more advanced)Next, we need to allow some basic mathematical calculations and comparison operations on our struct by adding some operator overloads (see my article: An Introduction to Operator Overloading in C#[^] for further explanation) and overriding the That's the struct created. To be able to use this as a property, we need to add a TypeConverter to it by applying the [TypeConverter(typeof(Size3DConverter))]
Size3DConverter (more advanced)This is where the real work gets done in a few overridden methods and our own I tried many combinations, and it seems to get our struct to work exactly the same as the built-in types we need to override the following methods.
Many of the methods call other methods, so it is not easy to explain them in isolation, so I won't attempt that here. If you follow the source code step by step, it should be self explanatory with this working example. The interesting point is we need to use Reflection and the struct's properties to dynamically create new instances when required. Control3DThis is a very basic user control (again, not production ready!) that I created to test and demo the It has one property - In useThe demo application uses a property grid that displays the properties of the History
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||