12,066,952 members (56,186 online)
<!-- Add the rest of your HTML here -->
When I saw a Microsoft's sample for using SQLXML that demonstrate a little project management application I said to myself, "It would be cool to have a similar progress control functionality in the dataset directly.". I work with data a lot and sometimes there are data items that are of a percentage type, that represent some progress#. It is very effective to show such data in a graphical way.
What we have here is a little sample of how to do such thing. It is a sample of
how to create a custom control derived from the
object, and how to write custom property modify dialog. The Component allows
the consumer to specify which columns are of the progress type within the grid, and the
grid then renders the progress based upon specified attributes given to the grid
object (like the color or style of the progress control).
The project for the custom control itself is a standard C# Custom Control project. When creating it I just set up the new project from the custom project template.
The whole component implementation is done in one file - CProgressDataGrid.cs
CProgressControls namespace (I thought that maybe it can be
usefull to create more similar controls and put them under the same
As you can see from the source, the class is separated into several areas, the
functional API of the component to access the attributes programatically (via
functionz or properties), - the region named 'accessor functions', and the main part,
implemented in the region named 'painting functions'. This region contains the
OnPaint handler. The logic is very straightforward, get the
list of columns that are marked as progress column types and then for every
cell in such column, get its value and draw the box there. Simple as that.
There are some properties you can set up into the control, via Visual Studio's designer or via the component's API:
There is the custom dialog used to select the columns for the progress control.
To implement your own property dialog you need to undertake several steps. First
you need to create your own new value editor class. In this case it is
as you can see it is derived from the
Basically you need to override two functions -
GetEditStyle function is called from the VS.NET framework to
retrieve the information about the type of the editor used for the property,
there are 3 types defined -
for exact description see the documentation for the
In our case we use
UITypeEditorEditStyle.Modal type. If you look
EditValue function, you can see that this is very simple
too. You can get the instance of the container if you wish, just type the
to your control's type. Here we have function call like:
CProgressDataGrid oGrid = (CProgressDataGrid)context.Instance;
On the next lines we create an instance of our dialog used to populate the list of
columns. I will not go into description of the form used to do that (called
CProgressDataGridColumnsValueEditorForm), it is not important
for this sample, but the source is included so you can observe that part of code
Once the property dialog ends it returns control to the
it is recommended to store the information if the data was changed in the
dialog and check it here, if this is the case then just copy the data to the
value variable and return it so the value will be stored
in the property.
I had a collection of type
ArrayList that held the columns
selected as progress bar columns, but whenever the persistent data was loaded
from the resource file, the deserialization process went wrong. I tried to find
a solution, but finally gave up, once I have some more time I'll dig into that
again, of course if you have any ideas how to make a collection as a property
persistent and updatable via the VS.NET designer, drop me a message. Anyway, in the
end I decided to do it with a little trick. The list is stored in the string property,
where the column indexes are delimited by the comma (,) separator, there is a
little helper function that turns the string into the
So, "How can I use that" you migh ask. First place the built assembly, or the
source, onto your machine and build it (in the case of the source). Once this is
done, go into the Toolbox window and right click when you have some form
selected, choose the "Customize toolbox" menu item and add the reference to
this assembly. At the end of the component's list you will see the
place it onto your form.
Then you need to specify a table style, and add some columns to the style according to the your underlaying dataset. Then you can scroll down and find the property group "Progress control", and specify the required color and type, whether you want to see the text or not, and the Table name within the data set. Once you have done this then click the "..." in the ProgressColumns attribute and use the dialog to select your "progress" columns. Save the project and build it.
That's it, if you have proper dataset bound to the data grid with some numerical data for the progress column you have chosen, then you should see the progress bars in that column.