Loading a Web User Control dynamically is rather easy: MyUserControl muc=(MyUserControl)Page.LoadControl("MyUserControl.ascx"); As a side note, I use this with AJAX, to load a user control, extract the rendered HTML and return it to be added javascriptmagically in a panel on the page.
However, when trying the same piece of code on Visual Studio 2005 with NET 2.0, I got numerous errors that MyUserControl was not found (The name 'MyUserControl' does not exist in the current context). Look, you moron, it's in the solution!! Anyway, I searched the web and discovered that even if I do load the web user control dynamically, I should also add a <@ register..> tag to the aspx, as if I would have the user control on the page.
Easiest way is to move the user control on the page, copy the register tag to the clipboard, undo the user control insertion, paste the register tag back.

Yesterday I had this problem where I needed to access the Session object from a webcontrol. I used HttpContext.Current.Session, after checking is HttpContext.Current was null. Then I've encountered a problem where HttpContext.Current was NOT null, neither were the Application, Response, Request and Server child objects, but Session was null.

After half an hour of searching on the web, I've decided to drill down on the problem and see what were the conditions under which it appeared. It seems someone had used the control in a UserControl that was loaded in the member declaration of the page. In other words, my WebControl was trying to access the Session object inside the constructor of a page. Apparently, the Session object is null in the constructor. Don't use private MyObject obj=new MyObject() anyway, since it breaks the separation of declaration and code, and don't try to access the Session object in the page Ctor.

My solution, after changing the offending piece of code, was to also change the WebControl to check if Session was null and if so, work without it. I also added a Debug.WriteLine('you are an idiot') message, for anyone encountering the same problem.

Getting back to programming, I am starting a small, but premiere project for Palm. These devices seem to be the work of the devil. The particular model I am programming for is something with a resolution of 240x320, with 64MB storage AND memory and with a 300Mhz processor.

Why?! When all computer screens are rectangular, with the width larger than the height, they make a device that is exactly the oposite. I mean, I understand they are meant to be hand held and all hand held devices are longer than they are wide, but it's still annoying.

Also, if I try to find a PC memory that is less than 256MB I would probably be forced to buy it second hand, yet they make a 64MB model? This also applies to the processor. Are they spending more money to make slower processors or is it just me seing things wrong?

Anyway, I found that working with DataSets in this environment is just awful. I started with a simple test project, 20000 rows in a 3.5MB XML file, loaded into a DataSet then displayed in a datagrid. First, the whole thing went out of memory and froze, then, when I fixed the memory problem by creating my own binary format and loading the file my way (oh yeah, I can see the roots of a XML sucks rant) the datagrid was very unwieldy.

Therefore I devised a ClusterGrid, something that shows clusters of rows in a datagrid and you just drill down and up on it. On my data, finding a customer in a 20000 rows table is 4 clicks away. First it shows 10 rows, representing clusters of 2000 people ordered alphabetically (ex: first cluster, from Alice to DeeDee). You click (or press with the finger, I have no idea how an actual Palm functions, I am using the emulator in Visual Studio 2003) on a cluster, you get another 10 clusters, with 200 people each. Then 20, then 2. Four clicks. Works like a charm. It seems a better deal than the scroll of the datagrid and I wonder why I haven't seen this before.

A small tip regarding the Palm Emulator. The default configuration is set on 32MB of memory+storage. If you want to at least have a functional program, increase it in the VS options, in the Mobile Devices tab. I couldn't make it larger than 64MB for whatever reason, but I never needed more and 32 is way too low.

This is a nice link about how to convert a UserControl to a WebControl.
Convert a Usercontrol to a WebControl - The Code Project - ASP.NET

Of course, afterwards it is best to take the time to really think the WebControl through, but for quick conversions like "I want a web control that has a datatable and a graph and another that is a textbox and a validator" it is perfect. Haven't really tested the result on real life user controls.

I don't count myself as a web developer. Maybe what I'm saying here is really basic, but here it goes.

1. CSS Style Sheets are good. Because you can change a lot from the file without changing the site. One could even imagine a complete site makeover only from the style. Remember that style can have color, font size, div position, borders, anything one can think of and it's not in Javascript :)

2. As a corolary to the first rule, style tags and color attributes and stuff like that inside the html file are NOT good. A colleague of mine has submited the idea that there are exceptions to this, like horizontal alignment in table columns and similar basic things. But I say NO! :) If there was a requirement for a certain column to be aligned differently, then it belongs to another style class, even if it's only one column in a thousand columns with the same alignment. I do admit that it's difficult and annoying to copy all the attributes of a class to another just to change something as trivial as the text color. Which brings me to point 3.

3. You can't nest or inherit CSS classes, which is really dumb. I mean, I want a base class to contain text font and color and everything and I want to create another class that says "I am like class1, but with bold font". You can't do that as far as I know, but you can combine classes. An element can have a class="redFont blueBoldFont" which will combine the two CSS classes, and they will overwrite each other. In this case the font will be blue and bold, as the blue color will override the red.

4. CSS classes can be selective. For example .redFont td { color:red; } will apply only to table cells within elements with the redFont class. That is different from the td.redFont notation, which tells what will happen with table cells that have the redFont class. I would suggest avoiding this type of notation if possible. Also, one can somewhat separate the behaviour of a class inside another class: .redFont .blueBoldFont { color:magenta; } in a css file or within a style tag will signify that the blueBoldFont class within the redFont class will have magenta color. Everything else being a combination of the two mentioned classes. This is a little akward, but it works. Warning! the notation .class1.class2 works in Internet Explorer only. The proper notation is the classes names preceded by a dot and separated by spaces.

5. One cannot configure custom html attributes or javascript events in style. That is a hinderance, but I don't know if adding it would have helped things. I mean, I do want to configure all the elements having a draggable class to have special mousedown and mouseup events, but this can also be done from javascript.

What does this mean? It means that a well designed site will have ALL the styling, even the position and size of movable elements, in a CSS file, as it will have all the Javascript in a JS file. This kind of file separation insures that the styling can be changed independently from the Javascript code and the HTML source. It also means that when designing a Web Control, creating a complicated style system for all its elements is not necessary. Just give a default class to each pertinent html element and then give the entire control a single configurable CSS class. Then combine classes to style each element.

Use this in a Javascript event handler to stop the event from continuing. Some events cannot be stopped, but the ones that can will be stopped by this in any browser.

function murderEvent(evt) {
evt.cancel=true;
evt.returnValue=false;
evt.cancelBubble=true;
if (evt.stopPropagation) evt.stopPropagation();
if (evt.preventDefault) evt.preventDefault();
return false;
}

and has 1 comment
Making a Web Control is not complicated. but things get weird when they need to postback values. Well, how does a Web Control postback? It implements the Interface IPostBackDataHandler which exposes two methods:

public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
public void RaisePostDataChangedEvent()

RaisePostDataChangedEvent should be called by LoadPostData, so you can just ignore it if you don't need it.
LoadPostData will not be called unless the WebControl is registered with the page for postback. I do this in the override of OnInit:
if (Page != null) Page.RegisterRequiresPostBack(this);
postDataKey is the "identifier" of the control, meaning that weird UniqueID with ":" instead of "_" separating the parent control ids from the children. You can use it or not.
postCollection is the Request.Form collection, The collection of all incoming name values.

example, a Label that also adds a hidden input field and handles the postback of that field value. Try changing the value from javascript and the text value will also change on postback.

public class UselessLabelPostback:Label,IPostBackDataHandler
{
private bool changed;
public bool Changed
{get { return changed; }}

protected override void OnInit(EventArgs e)
{
base.OnInit (e);
if (Page != null) Page.RegisterRequiresPostBack(this);
changed=false;
}

protected override void Render(HtmlTextWriter writer)
{
base.Render (writer);
HtmlInputHidden hih=new HtmlInputHidden();
hih.ID=this.ClientID+"_hiddenField";
hih.Value=this.Text;
hih.RenderControl(writer);
}

public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
string s=postCollection[this.ClientID+"_hiddenField"]; //not using postDataKey
if (s!=null)
{
s=HttpContext.Current.Server.HtmlDecode(s);
if (s!=Text) RaisePostDataChangedEvent();
this.Text=s;
return true;
}
return false;
}

public void RaisePostDataChangedEvent()
{
this.changed=true;
}
}

Important:
This is a control inherited from a Label, that's why I chose to render the hidden input manually. This has a few side effects. For example, the id of the label will be ucIPostBackTest1_UselessLabelPostback1 if the control is inside a User Control called ucIPostBackTest1. The id of the hidden field will be ucIPostBackTest1_UselessLabelPostback1_hiddenField only because I used the ClientID of the label when I manually set the field ID. For the same reason the name (the name attribute of a html item is the one that gives the postback identifier, not the id) will be the same.

The way to do it when starting from scratch is to add extra controls in the CreateChildControls() overriden method, use EnsureChildControls() in the PreRender or Render methods and the web control will render them all. Here the names and ids of the rendered child controls will differ and this is where the postDataKey comes in. But that's another story.

and has 0 comments
For a sneak preview of C# 3.0 a good starting point seems to be:
Future Versions

All the rows in an HTML table have a property called rowIndex, which is the actual index in the rows array. Table cells are in a similar situation with their property cellIndex. BUT, Internet Explorer chooses to interpret cellIndex as the VISIBLE index, rather than the internal one. Netscape, Mozilla and Opera do not exibit this behaviour. Funny thing, the rowIndex works in IE no matter how you hide the rows.

More detailed, style.display='none' makes the cellIndex of the next cells to decrement, while style.visibility='hidden' does not decrement the cellIndex, but keeps the formatting of the page, so you actually see a big empty space where the cell used to be.

I wouldn't have mind this if the Microsoft guys used another index to show the internal value, but they didn't! I have no idea what is the internal index of my cells anymore! Grrr!

and has 0 comments
Except the obvious one that override cannot be used on methods not declared as virtual, there is the little nag of how the original object will use the method internally. Mainly it will use its own not overriden code, but not the methods that hide its code.

Object A has a method M virtual. B inherits A and overrides method M.
With an instance of B, B.M() will run the code in object B, while M() inside the code of object A will also run the code in object B.

Object A has a method M not virtual. B inherits A and hides method M with a new M method.
With an instance of B, B.M() will run the code in object B, while M() inside the code of object A will run the code originally in object A.

Ex:

public class PrintStuff
{
public PrintStuff() {
PrintMe();
}

public void PrintMe() {
Console.Write('ME!');
}
}

public class PrintStuff2: PrintStuff
{

public new void PrintMe() {
Console.Write('new ME!');
}
}

a code like new PrintStuff2(); will output ME! while a code like new PrintStuff2().PrintMe() will output new ME!

and has 2 comments
I've always compiled and tested web applications on the company server, but then I found myself in need of debugging so I started a project on the local machine. Then I started to get random errors when compiling the code.

===Errors from hell===
Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: Access is denied: 'Some.DLL.Library'.

Source Error:


Line 196: <add assembly="System.EnterpriseServices, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
Line 197: <add assembly="System.Web.Mobile, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
Line 198: <add assembly="*"/>
Line 199: </assemblies>
Line 200: </compilation>


Source File: c:\windows\microsoft.net\framework\v1.1.4322\Config\machine.config Line: 198

Assembly Load Trace: The following information can be helpful to determine why the assembly 'Some.DLL.Library' could not be loaded.


=== Pre-bind state information ===
LOG: DisplayName = Some.DLL.Library
(Partial)
LOG: Appbase = file:///c:/inetpub/wwwroot/WebAppFolder
LOG: Initial PrivatePath = bin
Calling assembly : (Unknown).
===

LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Post-policy reference: Some.DLL.Library
===Errors from hell===

Do you want to know what was wrong? The Indexing Service rings any bell?

PRB: Access Denied Error When You Make Code Modifications with Index Services Running

Among my most disgusting duties is creating setup projects, mostly with Visual Studio. One thing I've stumbled upon is the way to pass arguments to Custom Actions.

Imagine you want to add parameters containing spaces like:
/dir "[ProgramFiles]" /dir2 "[MyDocuments]"
In the custom action arguments box write this:
/dir "[ProgramFiles]\" /dir2 "[MyDocuments]

That's the only way I could make it work. I still don't have any idea why.
So if you want to have a parameter with spaces in it, add a quot in front of it, but don't add one at the end. If you need to have other parameters after this one, end the quot block with backslash+quot.

Update:
Apparently, Windows Vista and its MSI engine doesn't support custom actions anymore. If you want to make your setup projects "worthy" of Vista, you should avoid using custom action.

Update July 2016: This post is really old and obsolete. In it I was describing getting both attributes of DOM elements and properties of the element object, a thing that should rarely be useful. Even so, I will update the post with the better way of doing this.

First of all, looping through the properties of a Javascript object:
// for ... in ...
for (var key in obj) {
console.log(key,obj[key]);
}

// using Object.keys (IE9+) and a normal for loop
var keys=Object.keys(obj);
for (var i=0; i<keys.length; i++) {
var key=keys[i];
console.log(key,obj[key]);
}

// using the Array.prototype.forEach function (IE9+)
Object.keys(obj).forEach(function(key) {
console.log(key,obj[key]);
});

// for ... of ... from the new ES6 specification
for (var key of Object.keys(obj)) {
console.log(key,obj[key]);
}

All of the methods above are similar, but not exactly the same. For example, the for...in loop goes over all the properties of an object, including those coming from its prototype. Object.keys (the other three methods, which all basically iterate over an array) only takes the set properties of the object itself. One can determine if an object has the property or it comes from the prototype using Object.prototype.hasOwnProperty and can determine if the object has a property of any kind using
var hasProperty = (typeof obj[key] != 'undefined')
or the relatively more recent
var hasProperty = (obj[key] !== undefined)
I say relatively more recent because in some browsers the value of undefined could be set. (Note the strict inequality sign, because undefined==null, but undefined!==null).

Now that we went through methods of iterating over the elements of arrays, it's trivial to enumerate the HTML attributes of an element, because they are stored in an attributes NamedNodeMap, which even if it looks like an array, with a length property and numeric indexes, it is not. forEach doesn't work, for example.

for (var i=0; i<obj.attributes.length; i++) {
var attr=obj.attributes[i];
console.log({
index:i,
name:attr.nodeName,
value:attr.nodeValue
});
}

Note that console.log(attr) will return a string like representation of the object because for some reason attributes have a valueOf overload that turns them into a string like key="value". You can also transform the NamedNodeMap into an array using Array.from (not in IE or Opera!) then use forEach, if that's your thing.

And below is the 2006 post... yuck!

I've always needed to read the attributes of objects in Javascript for my
custom controls. Imagine a tag like this:
<span id=test1 attribute1="value">
followed by a Javascript code like this:
test1.attribute2="anotherValue";

There are two solutions for reading the attributes of an object:
1. for-in loop:
for (var name in test1) alert(name+':'+test1[name]);
2. use the attributes property (the W3C DOM way)
for (var c=0; c<test1.attributes.length; c++) {
var attr=test1.attributes[c];
alert(attr.name+':'+attr.value);
}
Or, if you are fortunate enough to know the attribute name, you can use
obj.setAttribute(name,value);
value=obj.getAttribute(name);

How nice. Now the good part, these pieces of code work differently for IE
and non IE browsers. What a surprise.
IE:
- both loops show all the properties of an object, including methods,
attributes specified in JS code or in html tags. The functions specified in
a tag are returned as [object]s.
- also setAttribute and getAttribute work the same, returning object
properties or tag attributes
FireFox, Opera and Netscape:
- the for-in loop returns only the object properties and methods, NOT the
things defined in the HTML tag
- the attributes loop returns ONLY the tag attributes
- getAttribute will only return the tag attribute while setAttribute will
change only the attributes, not the object model
- in the case that a tag attribute is automatically transformed by the
browser in an object property (like an event onchange="test();")
obj.onchange will return a function object, while
obj.getAttribute('onchange') will return a string

Therefore the only way I found to loop through all the properties of both
html tag and DOM object is by using both loops. ex:
function PassAttr(elem1,elem2) {
for (var c=0; c<elem1.attributes.length; c++) {
var attr=elem1.attributes[c];
if (attr.name.substring(0,5)=='list_')
elem2.setAttribute(attr.name.substring(5),attr.value);
}
for (name in elem1)
if (name.substring(0,5)=='list_')
elem2.setAttribute(name.substring(5),elem1[name]);
}

Global.asax and Session_OnEnd

You may have already used it, but I just found out about it. There is a
global.asax file in each web project, it contains a lot of events that one
can use, like Application and Session start and end events.

Now, I tried to make Session_OnEnd to work well for the last hour, the trick
is follow these rules:
1. The session must be in InProc mode
2. In the Session_OnEnd (and Application_OnEnd) you cannot use Server,
Response or Request objects. So Map.Server will fail, for example. Also,
throwing exceptions will not cause any display on the actual page or new
pages, they just go unnoticed. This also means HttpContext.Current doesn'
work.

That is it. The Session_OnEnd event will fire on:
1. Session.Abandon
2. session timeout

Download this nice utility from Microsoft:

Internet Explorer Developer Toolbar

Then go in Internet Explorer and add the Developer toolbar. It is very nice
for web developers and javascript programmers

Also, check this out:
Code Spy