July 2005 - Posts

I've released the newest version of the Reflector.Diff at http://www.codingsanity.com/diff.htm. There's a few definite bug fixes, and a few hopeful fixes (i.e. I couldn't replicate them, but fixed some issues that may have caused them).

I've also cleared up the problem with assemblies having the same name, version, culture and public key. They are considered as the same, and thus cannot be differenced, and it now displays that in the label above the destination difference list.

I didn't find much information about this, so I'm working off guesswork and a few little tests I did.

There's a couple of really nice enhancements to validation in Whidbey. First off, for those of you who don't like forcing the user to remain in a field when there's an error with it, you now have the wonderful AutoValidate property. This can be one of the following values: Inherit, Disable, EnablePreventFocusChange, and EnableAllowFocusChange. Inherit is only available for inherited forms. Disable will mean that your controls will not raise their validating event when you tab out of them. EnablePreventFocusChange will mean that if the ValidatingEvent sets it's event argument's Cancel property to True then the focus will remain in the control, in other words the same behaviour as .NET 1.1. EnableAllowFocusChange will allow the focus to be lost even if the validation fails.

In 1.1 I had to leave the Cancel property as false, and rather keep track of validation success\failure myself in order to allow what EnableAllowFocusChange now gives you.

Now, for the real fun. There is now a method on Form called ValidateChildren. This little sucker goes and validates the various controls, and returns a true/false to you based on whether any of them set the Cancel to true (i.e. it returns false if any Validatings had their Cancel set to true). It's the nice little one-stop shop for validation. Not only that, but it comes with an overload that allows you to specify what kind of controls should be validated. This overload can take a bitfield enumeration called ValidationConstraints. Each flag indicates something that limits the validation:

  • ImmediateChildren - Means the validation will only be performed on items contained directly in the forms Controls collection. A field on a Panel in the form will thus not be validated.
  • Enabled - Only controls that have their Enabled property set to true will be validated.
  • Selectable - I assume that this means that only controls that are able to receive focus will be validated, but I'm not sure on this one.
  • TabStop - Only controls with their TabStop property set to true will be validated.
  • Visible - Only controls with their Visible property set to true will be validated.

This all makes validation a lot easier and more customisable. Your OK buttons code now becomes a simple if...then...else such as:

if (ValidateChildren(ValidationConstraints.Enabled | ValidationConstraints.Visible))

{

// Save form data

DialogResult = DialogResult.OK;

}

else

{

// Display error dialog

}

Coupled with the ErrorProvider control, this allows each field's Validating event to contain exactly the code required to validate that field as well as simplifying the validation of your entire form. All that, and you get powerful control of the details too!

Caveat

For some reason, the ValidateChildren method does not pick up controls inside a TabPage. I haven't tested all containers, so there might be more that have this problem.

I've been quite busy lately. Both a combination of work and play busy so it's not all bad. Anyway, that's my excuse for not blogging for so long. I've also been neglecting my newsgroups, I should be able to slowly come back online over the next few weeks.

Anyway, I don't have much for this post, merely a little trick I used to simplify my life recently. I had a situation where I had a component, which had numerous child components placed on it. Now, I was really interested in two particular types of these child components, and I wanted to expose them as collections. In order to avoid duplicating code and also to avoid worrying about keeping a collection in sync with the component, I created a ComponentCollection<T> class. You create it, passing in the parent component, and it will then present all child components of type T as if they existed in their own collection.

In reality they don't, I simply use iterators to present a subset of the child components as if they belong to the “collection”. Addition and removal simply add and remove from the parents components collection. I have posted the code at my web site. It's not very efficient, so I wouldn't use it for large component sets, but it certainly saves time and removes all problems of synchronising a collection with the underlying components.

The combination of generics and iterators allow for some very powerful idioms, and some very nice shortcuts. A brilliant example is the Power Collections project. Some of the collections in there got me drooling just coming up with funky ways I could use them. As for the Algorithms class, well, it brings back fond memories of the STL. Happily it doesn't appear to bring back the nasty memories with it.