"[...] In general, we are dropping 3rd party components that are not critical to our application. For example, we have been using [...] and [...] but have had occasional licensing and other errors with those as well. And since they don't provide any absolutely necessary functionality we will make do with the simpler toolbar and grid provided in Visual Studio. Your Smart PropertyGrid, on the other hand, provides functionality that we couldn't do without. [...]"
Some days ago, I was asked by a visitor if it is possible to edit an IP address in Smart PropertyGrid with a specialized editor. The short answer was no. But then I realized that the FieldPackEditor would make a wonderful IP address editor. So I derived a new editor from the base class, created special IpAddrSegmentFieldPack and IpAddrSegmentField classes and voila!
Like with other field pack editors, you can show updown buttons, handle a null value, have fixed-width fields or not, set the Text and Value properties and use all the usual keys to edit the address. I think this is the first time we have a so complete IP address editor for windows forms (let me know if there is some competition). You can now play with it in the updated sample and you will see it soon in the PropertyGrid too.
Yes, this is like a new year beginning here. I was in vacations in France during three weeks for a break from VisualHint, with family in Normandy by the sea not far from the american cemetery for those who know this place. This was very relaxing and the kids had a lot of fun with the beach activities (when one lives in Montreal at four years old, the sea is something new). Now that I'm back, this is time to take stock of the VisualHint's future. So how is it going here you will ask. Here is the short answer:
I highlighted May 2006 because at that time I posted a message titled Incredible month of May. You can now see the comparison with my last recorded month. This has almost doubled, so yes, I’m very happy about the evolution of Smart PropertyGrid.Net and its sales. Notice the two spikes, one downward from the mean curve and one upward. The first one is August 2006: activity was very low and I also took some vacations. The second one is November 2006: I can’t really explain it but it seems like a lot of companies wanted to do their shopping before the month of December and Christmas.
So now what? It took me up to today to almost clear all the cutomer requests received during my absence. Still a few ones and I will be done. All the fixes generated will be available very soon in a maintenance release, I guess sometime next week. Then I will come back on the new FieldPackEditor product to finalize it and take it out of beta. Once done, it will be time to define the major new features of SPG v.3. I think the summer break with its low activity will be a very good time to do that. For those who take their vacations, I wish a lot of fun and rest.
Before releasing version 1.0 of Smart FieldPackEditor.Net I must ensure that the support for null values is really complete. So what does this feature really involves?
First let’s remind in what contexts a DateTimePicker can operate:
It can be a standalone control and completely encapsulate a DateTime value.
You can manually bind one of your properties to the component’s Value property.
You can embed the component in a container like the DataGridView. In this case, the component will be automatically bound to a particular column of a database table via a DataSource.
You can embed the component in a container like the PropertyGrid. This will bind the component to a DateTime property somewhere in your code.
In the first case, the support for null values is straightforward. The component stores the DateTime value as an object so it can use anything for the object representing a null value.
We have to think a bit more for the other cases. What can be the type of your property in a target instance? Obviously this can be an object (not very common to store a date but still feasible), a nullable DateTime (aka “DateTime?”) or a DateTime. In the first case, there is again no difficulty: we can assign anything we want to represent a null value. In the second case we have less choices: it can be null or a particular DateTime value that is out of the bounds specified by the MinDate and MaxDate properties of the DateTimePicker (anything before 1753 will be fine). In the last case, with a DateTime type, there are no choices: you can only use a specific DateTime value like 01/01/0001 for example.
Now let’s relate the context of use with the data type you have in your client application:
In case 2, you can target any of the three data types we just saw. The value representing null will be chosen in accordance with the restrisctions seen above and setup in the editor.
In case 3, the value representing null will usually be DBNull.Value. But for historical reasons you may have a specific DateTime value in your database that represents the null value. In both cases, again, the editor must be setup for that.
In case 4, well, it’s like case 2.
Everything that has been mentioned so far implies that we need a set of properties to properly setup the DateTimePicker:
NullValue: instructs the editor about what will represent a null value. It will typically be null, DBNull.Value or a specific DateTime value. But it could also be a string like “nothing”.
NullText: the string displayed in the editor when Value == NullValue.
HasValue: convenient property to test for nullity.
If you use the DateTimePicker in other very specific contexts and you need support for null value, please let me know.
Even so Smart FieldPackEditor.Net is still in early beta, I received this week-end a message from a developer working at a big israelian company about the support for Hebrew. Here is an excerpt:
I examined the control and let me tell
you it is very professionally designed
and implemented; way to go! Also the
RTL and Hebrew are working great, a
feat not easily performed by many
Supporting RTL is something new for me and when I designed the component I even hadn't the RTL languages installed on my machine, so this message is a real reward for me. Now I know that the code I produced was not just a shy attempt to see if RTL languages could be handled. They can! And needless to say that I am armed to prepare the RTL support in Smart PropertyGrid.
This developer also sent me some great feedback about the sample application. That's why I fixed some issues over the week-end and republished a new build of the beta package.
Time permitting, I sometimes haunt the newsgroups and developer forums to help when the PropertyGrid is involved. Last week, a poster noticed a very subtle issue concerning .Net 1.1 and .Net 2.0 and I decided to know more about it. It appears that the MS PropertyGrid behaves differently in these two versions of .Net. Here is an excerpt of the original request for help:
... When there are multiple objects
selected, and an object property value
is changed in the grid, it is
assigning the same object instance to
each of the selected objects in .Net
1.0, but in .Net 2.0 it is assigning different instances...
The poster also noticed that the culprit was the method SetValue in the MergePropertyDescriptor class. In .Net 1.x it was simply calling PropertyDescriptor.SetValue() with the same new instance for the target properties but in .Net 2.0 it tries first to make a copy (except if we have a value type) by trying different techniques in a method called CopyValue:
Clones the value if its type implements ICloneable.
Creates a new copy of the value by calling the constructor of its type if the attached TypeConverter can convert to InstanceDescriptor.
Creates a new copy of the value by first converting it to a string and then back to an instance of the value type.
Creates a new copy of the value by serializing it into memory and deserializing it to an instance of the value type if, of course, the type implements ISerializable.
If all tries fail, then the original value is returned.
My thoughts about this issue is that the behavior should be chosen by the developer. In some cases we will want to assign to the target properties distinct instances of the same value and in other cases it makes more sense to assign the same value as if it was a kind of singleton. I tend to prefer what .Net 2.0 does but hey, having the choice is better. I will check if I can offer this choice in SPG, which so far behaves like .Net 1.x.
With the MS PropertyGrid however, I first thought that there was no solution since CopyValue can't be bypassed. But there is one. Implementing this solution for every property would be tedious but for just some of them, when you want to avoid a multiplicity of instances for cost reasons, this can be useful.
Attach a TypeConverter to the type of your property (this won't work if it is attached to the property itself) and override the ConvertTo method so that it will convert to an InstanceDescriptor class. In the class corresponding to your property type, add a static method that will be responsible for supplying a unique instance per possible string representation (it could be done elsewhere like in the TypeConverter itself). In the converter, the InstanceDescriptor will point to this class method.
An example is better than a long explanation so here is a short sample.
Note: this solution won't solve the problem of the original poster unfortunately because for him this happens at designtime and the TypeConverter, quite complex, can't be modified. However, at runtime, it can help in a variety of cases.
To conclude this series of videos, I'll show what can be done with the editor base class. Everything is inside to handle a set of packs and fields which can edit any predetermined data. And since a field is pretty abstract (after all, this is just a rectangle in which we can draw), I'm sure that some nice scenarios will appear after the product is released. Anyway, here is the show:
If there is no last minute drama, the beta will be available next week. If you want to be informed, simply monitor the rss feed or subscribe to the mailing list on the homepage. And of course, feel free to leave some comments here.
In this third video, I show several features of the FieldPackEditor: how flexible it is to bind a DatTimePicker to a data source, how independant field packs in the same editor can be bound to different sources and how the editor can be used in the DataGridView as a perfectly well integrated inplace control. Keep in mind that this editor will also be compatible with Smart PropertyGrid.Net and integrated in place in its value column.
Some days ago I came across a blog showing the trials and tribulations of a developer trying to display and use the standard DateTimePicker in the DataGridView. This story is really typical of all the considerable efforts one have to make in order to get a semi-viable solution. So far I was not even considering touching the DataGridView. It was an unknown component to me and I was not aware of its extensibility to enable custom editors to be used in a cell. After readind this article I jumped on the challenge and decided to integrate Smart FieldPackEditor.Net to the grid.
While SFPE is not even in beta yet, it took me one day to get almost everything running smoothly. By everything I mean:
Nice insertion of the editor inside a cell. No text shift. Back and Fore colors of the cell used by the editor.