It started with a simple request for a custom control to perform some validation. Seems easy enough, but it is not. Sure, there is an easy solution and that is to create a composite control, containing the original control and a normal validator, but that means you don't inherit from either control and you have to copy all the properties and methods you are interested in. If, as I did, you do not like this solution, you will soon find out that there are a lots of obstacles to be conquered if you want all the features of a validator, the first of which being that a control cannot easily change the Controls collection of its parent. It would be bad design. Therefore simply adding a Validator from inside the control does not work.

Let's start with what others did: Self Validating ASP.NET Text Box. This CodeProject article shows how you can build a control that is validated only on the server side and implements the IValidator interface. However, you will notice that it did not implement the ValidationGroup behaviour. And that is due to a simple fact: there is a method of the Page class called GetValidators(string validationGroup) that is used all around ASP.Net. It looks kind of like this:

public ValidatorCollection GetValidators(string validationGroup)
{
if (validationGroup == null)
{
validationGroup = string.Empty;
}
ValidatorCollection validators = new ValidatorCollection();
if (this._validators != null)
{
for (int i = 0; i < this.Validators.Count; i++)
{
BaseValidator validator = this.Validators[i] as BaseValidator;
if (validator != null)
{
if (string.Compare(validator.ValidationGroup,
validationGroup, StringComparison.Ordinal) == 0)
{
validators.Add(validator);
}
}
else if (validationGroup.Length == 0)
{
validators.Add(this.Validators[i]);
}
}
}
return validators;
}
Notice anything? There is no mention of IValidator, instead only BaseValidators are sought and the reason the IValidator approach works at all is the line before last where a validator is added to the list if the validationGroup parameter is empty. That is, it will work with IValidators but only on Buttons or other postback controls that have an empty ValidationGroup.

So let's start from the idea of the original article: an IValidator TextBox control with server validation only. For simplicity I will compare the value of the control with a constant string and fail the validation if the comparison fails.

Click to expand


You notice that the entire logic of this method is that the validators in the Page.Validators collection will be validated when need arises. In order to implement the ValidationGroup behaviour, we need to either fool the GetValidators method or to actually add a BaseValidator to the collection, not the IValidator control. I would have preferred the first method, but GetValidators is executed not only in Page.Validate but, being public, can also be executed in other situations (and in fact it is called by every control that wants to cause a postback).

My first attempt was to simply add a dummy validator to the collection, with the proper ValidationGroup set. It worked for the client side (we'll get to that) but then it failed miserably when Page.Validate tried to loop through the collection. I was forced to create my own validator control that inherits from BaseValidator. Do not worry, though, it is very lightweight and does not need to be added to the Controls collection. Here is the source:
Click to expand

public class DummyValidator:BaseValidator
{
private readonly IValidator _realValidator;

public DummyValidator(IValidator realValidator)
{
_realValidator = realValidator;
}

protected override bool EvaluateIsValid()
{
_realValidator.Validate();
return _realValidator.IsValid;
}

protected override bool ControlPropertiesValid()
{
return true;
}
}


Note: the following code has a property called ValidationGroup. The TextBox already has it, for its own AutoPostBack behaviour. I left it there, though, because you might want to use this on a control that doesn't have it natively.

Now the code for the ValidatedTextBox class looks like this:
Click to expand

private DummyValidator _dummyValidator;

protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (Page != null)
{
_dummyValidator = new DummyValidator(this){ValidationGroup = ValidationGroup};
Page.Validators.Add(_dummyValidator);
//Page.Validators.Add(this);
}
}

protected override void OnUnload(EventArgs e)
{
if (Page != null)
{
//Page.Validators.Remove(this);
Page.Validators.Remove(_dummyValidator);
}
base.OnUnload(e);
}

private string _validationGroup;

public string ValidationGroup
{
get
{
if (_validationGroup == null)
{
if (ViewState["ValidationGroup"] == null)
ValidationGroup = "";
else
ValidationGroup = (string) ViewState["ValidationGroup"];
}
return _validationGroup;
}
set
{
_validationGroup = value;
ViewState["ValidationGroup"] = value;
}
}


So the ValidationGroup is now working on the server side since there is an actual BaseValidator in the Validators collection calling the Validate method of our control. Since the DummyValidator class doesn't implement any specific behaviour, it can be reused for any type of validated control.

Now for the client side part. The client validation scripts work with a javascript array called Page_Validators. The validators are rendered as span elements (where the error message is displayed) and the array holds all these elements, with some extra properties like isValid, errorMessage, evaluationfunction, controltovalidate, validationGroup, focusOnError, enabled and display. The first three are like the IValidator members, only in javascript, controltovalidate is the client id of the control to be validated while focusOnError is used to scroll the page/container in order to see the invalid control without looking all over the page to find it.

All the ASP.Net validation functions are in a javascript file called WebUIValidation.js and embedded in the System.Web.dll library. We need to load it in order for validation to work. Then we need to render a span element and set its attributes. Lastly, but most important of all, we must create a function that will evaluate the validity of the control.

I will just post the entire source, since all the client code is practically copied from the BaseValidator code.

Click to expand


There are several things you need to take care of.
One of them is the client display of the validators. Normally, a validator's span element is rendered with the ErrorMessage as inner html. The ASP.Net framework then changes the visibility of the span depending on the validity of the control. I have chosen to not render the error message, as I wanted a different behaviour (in this case, a red background). The span element is still shown and hidden, but being empty, there is no visible effect.
Another thing is when you would use validation summaries. The error message is being rendered as a property of the span. It WILL be used in the summary, even if it is not normally displayed.

This code will work with almost no change for any control, so you could encapsulate it into a ValidatorHelper class or something. The only variants are the Validate method and evaluatefunction function.

Also note that having inherited from BaseValidator, I bypassed the normal functionality of the default validator controls. If you want to inherit from one of those, like RegularExpressionValidator, you might encounter problems, especially for controls that are not normally validated and for which the normal validator controls try to get their value. Take a look at the ValidationProperty attribute that you might need to use to decorate your control in order to work with default validators. Also, the javascript behaviour is to look for a control that has a value attribute. If not found it searches deeper into the children. So if you want to use a default validator, you might want to add script to keep a value attribute updated on the validated control HTML element.

And that was all.

It is weird that this doesn't happen with all types of Visual Studio projects, but only with Web apps. You have all those annoying .MySCMServerInfo files that pop-up in your check-in window and then cause errors because SCM knows they should not be checked in.

Enter StackOverflow with a really good solution: Hidding source control files within Visual Studio’s solution tree. No need for me to copy paste, just remember you need to restart Visual Studio for this to work.

Today I've updated my computer with the latest patches from Microsoft and then, starting a project, I noticed that it didn't look right in Internet Explorer 8. For example a table with an empty td of width 1px looked as if having 4px. Setting it to 2px or above made it look of having 2px or whatever value I had chosen. I have solved the situation by adding content to the td in question (a simple &nbsp;), but before today I have not had this problem.

Update: This blog post was previously called "Microsoft updates breaking changes?" but in the meanwhile I have determined what the problem was. It was the zoom! I had my IE set to 75% zoom. That caused the weird behaviours and appearance.

The solution is still working, but the problem should be rephrased as "Why do the widths of td elements behave strangely when setting smaller zoom in Internet Explorer?".

Just for kicks I tried duplicating the problem using the zoom:75% style setting on body and, even if it looked bad too, it was a completely different behaviour.

You may get an error of the form Cannot add content of type 'System.Windows.Style' to an object of type 'System.Windows.ResourceDictionary' when working with WPF and your first reaction would be "What?! Why not!?". Well, the issue is very simple, only it stems from another source entirely: you've just tried to add a Style with the same key as another previously entered style.

I believe this is something that any decent WPF programmer will laugh about, but there it is: I had this control derived from ContentControl and, of course, somewhere in the template I had a ContentPresenter. It all worked very well until I added a resizable option. I had two of these controls on the page, the first would contain a Grid, the other an ItemsControl. When I resized vertically the control, the ItemsControl would remain unchanged whether I made the height bigger or smaller. The Grid, though, would remain the same if enlarging the container and then squash when the size of the container got smaller than its auto size.

I have to say that I think my solution is really silly, but since it works: I've put a ScrollViewer control around the ContentPresenter in the my control template and then set its VerticalScrollBarVisibility to Hidden. This more or less is the same thing as setting overflow:hidden on the web.

Short (but true) story: I was compiling this solution with a lot of projects in it. And one of these projects had some post-build events set to run which copied the resulting dll in an Assemblies folder. Only it failed.

On building the project I was getting an error: The command "[Complete command]" exited with code 1.

What was weird about it is that if I copied the command in a batch file and ran it, it would work perfectly. After trying a zillion things I've stumbled upon the condition of build events Run the post-build event: which was set to On successful build. I set it to Always and voila, it worked.

But I still needed to know what was going on, especially since it would make no sense to run the copy command if the build has failed. So I switched it back to On successful build. Surprize! It also worked.

Therefore, the silly solution for a problem that doesn't make much sense is to switch to always run the build events, build successfully, then switch back and build again. Fun!

Usually this happends in IE, but it may happen in a various other situations, given that Internet Explorer is famously bad, but also has to fight with all the backward compatibility and that new "innovative" browsers are on the way.

Let me make this easy: if it's a weird sixteen pixels difference (or somewhere around 16) then you probably are in one of these situations:
  • scrollbars - that you may not see, but they are there. I've just met this issue with a table of 100 percent width placed in a div of 100 percent width and it happened in IE8!
  • line-height - this is usually with Internet Explorer 6 or less, divs that are 16px in height when they have no content and have a specified lower height
  • font-size - also something from the older browsers

and has 0 comments
Nothing interesting to say myself, so I am linking to random blog posts :) Here is one that describes 31 types of refactoring, with examples and everything:

31 Days of Refactoring.

I had this expand/collapse div on which I was using slideToggle to make it look good. However, in quirks mode (HTML Transitional 4.01 DocType) and on IE7 the div would briefly pop up after collapsing, showing an annoying flicker. It seems that Internet Explorer has a problem rendering stuff with height 0px.

The solution I found: replace target.slideUp(speed,callBack) with
var h = target.height();
var cssHeight=target.css('height');
target.animate(
{ height: '1px' }, speed, function() {
target.hide();
target.height(h);
target.css('height',cssHeight);
callBack();
}
);
I have also created a jQuery ticket to suggest they use the same method in the library itself.

Update 1 Sep 2009: I have added the cssHeight variable to restore the actual css height settings, not just the height.

Update 21 May 2011: commenter Mads shared a more elegant solution in the form of this script:
(function(){
// Define overriding method.
jQuery.fx.prototype.hide = function(){

// Remember where we started, so that we can go back to it later
this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
this.options.hide = true;

// Begin the animation
this.custom(this.cur(), 1);
}
})();
used anywhere after the jQuery include. Thanks, man!

The problem: you create an abstract class that inherits from something that can be designed in Visual Studio, like Form. Then you inherit another class from this abstract one. And when you get into the Visual Studio designer you see a nice colorful error message: The designer must create an instance of type 'bla bla bla' but it cannot because the type is declared as abstract.

The solution is detailed in a post of Brian Pepin: use the TypeDescriptionProviderAttribute decoration on the abstract class in order to tell .Net (thus to Visual Studio) what concrete type to declare and instantiate should the need arise.

Update: Brian's article is no longer available. I will update the link as soon as possible. Meanwhile, try this article from Microsoft.

Update: I have found the original article somewhere else and relinked it. Also, check out the fourth comment on this entry, where TrevDev links to a Microsoft Connect bug on the TypeDescriptorAttribute which suggests the attribute is not used correctly. That probably explains why people on VS2008 have problems, while the solution works on VS2005.

Now, all you have to do is read the post in question, with one reserve. The blog entry (and some other pages I have found on the net) say that this only works for Whidbey (VS2005), but I am using VS2008 and it worked just as well. However, for a second opinion try this CodeProject article that uses a little conditional compiling trick to switch from abstract classes with abstract methods and properties to normal classes with not implemented classes and methods based on debug/release modes. I kind of dislike the approach, mostly because it needs more effort to implement it, but it could help people that have this problem and maybe use some other IDE other than VS2005 or VS2008.

I have this very precise requirement I am working on: a collapsable panel that has rounded corners of fixed size and a background image or a gradient, both needed to stretch with the panel, which would be vertically resizable by javascript. Also, the HTML 4.01 Transitional DocType will be used on pages. The only respite given is that the solution should work only on Internet Explorer.

I have first tried some jQuery alternatives, but I am not happy with them. Even if the rounded corners would have been what I was looking for (and they were not), the background stretching is a difficult feat to master in HTML. Even so I have cropped up something that takes the entire content of the panel and relatively positions it over an absolutely positioned image that is then stretched by javascript to its needed dimensions. However, all this relative and absolute positioning requires a lot of event driven javascript (when the events themselves are not really there, so I must also create new browser events!) and it has been shown to break either layout or functionality like the one for collapse.

Enter VML, an obscure web technology from Microsoft that has a RoundRect object that can have a fill of an image OR a gradient, stretched to the full size of the element. Can you see it? I was already planning the blog entry, detailing the masterful ASP.Net control that would change the world of web development forever.

Back to real life now. First of all, the RoundRect element does have an arcSize property that determines the percentual size of the rounded rectangle. By percentual, I mean that resizing the element would lead to larger corners. I don't need that. Another nice surprize was that I can't either read or write the arcSize property from Javascript, it throws an error. People have complained about it before and their solution was to disconnect the element from the DOM, change the arcSize, then add it back into the DOM. It didn't work for me.

After wasting about half a day with this, I concluded that the RoundRect was a lost cause. Enter Shape! A Shape is a VML element that can take any shape determined by a path. The path has interesting primitives like qx and qy which mean "draw an arc to this position". It appears that a Shape can easily take the place of the RoundRect. What was even nicer, the path attribute could be changed at will by javascript.
<v:shape strokecolor="blue" strokeweight="1" coordorigin="0 0" coordsize="203 103" style="width:200px;height:100px"
path="m 2,0 l 198,0 qx 200,2 l 200,98 qy 198,100 l 2,100 qx 0,98 l 0,2 qy 2,0 e"></v:shape>
The code above is a 2 pixel rounded corner rectangle of size 200 by 100. To add a stretched background image or gradient, a v:fill element must be added as a child of the shape and you are done!

I was extatic, finally having solved the problem that had haunted me for days, until I noticed that, unless I specify the width in pixels, the shape would behave really strange. I was commited not only to a panel that needed to be defined as percentual or expanding with the content, but also to HTML 4.01 Transitional DOCTYPE. In this particular situation, placing two shapes in a table, let's say, even if the table size was specified or, indeed, the sizes of the TD elements, in percentages or pixels, the shape would just expand to its maximum possible width.

I got stuck here. The control worked perfectly when the width was specified in pixels. Anything else just throws a big wrench into the works and makes it wanna go boom. In a fit of anger, I just replaced the obsolete doctype with the modern XHTML 1.1 one. And it worked, but only on Internet Explorer 8, not any of the previous versions of the browser.

Therefore my only option now is to either abandon the technology completely or to convince people to change the DocType for all their legacy pages. How fun is that?!

And before you write the usual crappy "Microsoft sucks! Internet Explorer sucks!", try giving me a solution for my request that would at least work in another browser. Was it so difficult to recognize the need for a stretched background image and custom shaped containers ?!

I was trying to do this update, but I wanted done in a specific order. I have found two solutions. One is to use a Common Table Expression, which would look like this:
WITH q AS (
SELECT x,y,z FROM SomeTable
ORDER BY z
) UPDATE q
SET x=y+z
Strangely enough this updates the SomeTable table in the order of z.

However, I had to do it in SQL 2000, so Common Table Expressions were not available. The only other solution I could think of was a temporary table with an identity column:
CREATE #temp (
realid INT IDENTITY(1,1),
x INT,
y INT,
z INT
)
INSERT INTO #temp (x,y,z)
SELECT x,y,z FROM SomeTable
ORDER BY z
UPDATE #temp SET x=y+z


The most difficult part of the task was to not think procedurally. SQL is a functional language and one must think differently. Weird is I knew that I had to think in a functional way and I said it out loud when I started the task. It took a few hours of trying to create recursive functions or emulate loops in SQL before I could change my thinking. Using SQL in a procedural way, even if possible, means using something in the wrong way.

I was having real trouble with an html menu. Every time I would move the mouse over an item, a large gray area would appear over the screen. This only happened on Internet Explorer 7, not Internet Explorer 8 or any other browser. When I changed the Doctype from XHTML to HTML I reproduced the error on IE8 as well.

Strangely enough, when I first found the source of the problem, a border of 899px , I thought it was a browser javascript incompatibility. How could it be differently? The CSS was mine and the JS was not. Obviously it was their fault. However, after reproducing the problem in IE8, I could use the more advanced developer tools available and I realised that the strange border width was not part of the element style, but the CSS class style itself. It was there, the interpreted style for my menu control class: border: 899px;.

I rechecked the CSS and I found the actual problem: no hash in front of the colors! So the browser found something like D8C89A instead of #D8C89A, did a weird parse on it, got 899, then considered it a size in pixels!

Hopefully, someone will read this and save themselves a lot of grief and time.

The Infragistics web controls have a way of saving design time settings into XML files and then loading them. You can do this either by loading the presets in the designer or dynamically from code, using the LoadPreset method. It accepts Stream, TextReader and string parameters and it is pretty easy to use.

The problem is that it doesn't work in inherited controls! The explanation is that a piece of its code is searching for the root element of the XML file by getting the assembly defined TagPrefix and then adding to it colon and the name of the object.

In other words, I had a control that inherited from UltraWebGrid, and in the ASPX it looked like omega:OmegaGrid, when styling it with the designer and then saving the preset, it created an XML that has its root element . Since my assembly had no assembly TagPrefix defined, it was looking for ":OmegaGrid" and failing.

The solution was to add the TagPrefix assembly attribute: [assembly: TagPrefix("Super.Desktop.GUIControls.Web", "omega")] in the AssemblyInfo.cs file.

Now, that title doesn't much, but it's the only one I could think of, because I haven't yet determined the source of the problem. Baiscally, what happends is that there is a difference of behaviour between style included directly into the page and actually using javascript to add to the head of the page a dynamically created link element.

I have no idea what exactly is going on, but I will try to explain it based on the evidence. There was this menu control, an Infragistics Web Menu from the NetAdvantage 9.1 suite, that, given the right styling, would look exactly like what I wanted. After setting that style in a css file I decided to load it using a javascript dynamic load just in case the control would be rendered only on asynchronous postbacks. And it worked perfectly. In IE8, Chrome and FireFox. However, when tried on IE7, it exibited the strange behaviour that, on mouse over, the entire table that the menu was rendered as expanded to fill the screen and was completely blank. After extensive attempts to capture the element with Internet Developer toolbar I noticed that the border-bottom-width and border-left-with were abnormally high, like thousands of pixels.

As of now I know not the cause of this. I can tell you, though, that moving the same style from the dynamically loaded CSS into a statically loaded one or by copying that style in a style tag in the page fixed the issue. I really hope it helps someone lose less days of their lives attempting to see what is going on.

Also, if you know the cause of this, or maybe other pages reporting the same behaviour or, I dare hope, a fix, please let me know.