The GridView is nothing more than an oversized DataGrid. The internal concept is completely rewritten, as far as I see, though. For example, Columns are not called columns anymore, they are DataControlField. Well, I stumbled upon one situation where I needed to format the autogenerated columns in a GridView. Normally, you could take the Columns collection and change the DataFormatString property for each column, but autogenerated columns (or AutoGeneratedField) are not part of the Columns collection. More than that, AutoGeneratedFields are nothing more than BoundFields with lots of useless restrictions on it like being a sealed class and throwing errors when trying to change some properties (like DataFormatString).

The first step is getting hold of the autogenerated column. Luckily the GridView control has a virtual method called CreateAutoGeneratedColumn which returns a AutoGeneratedField. So create a control that inherits GridView, override this method, take the generated field in the base method, change DataFormatString. I couldn't find any way to do that except with reflection. I noticed that the value of the DataFormatString property was stored in the ViewState of the AutoGeneratedField, so I used reflection to get to it, then I changed the value.

This is the code:
protected override AutoGeneratedField CreateAutoGeneratedColumn(
AutoGeneratedFieldProperties fieldProperties)
{
AutoGeneratedField field =
base.CreateAutoGeneratedColumn(fieldProperties);
StateBag sb = (StateBag)field.GetType()
.InvokeMember("ViewState",
BindingFlags.GetProperty |
BindingFlags.NonPublic |
BindingFlags.Instance,
null, field, new object[] {});
sb["DataFormatString"] = "{0:N}"; //or the format string you prefer
field.HtmlEncode=false; //see update
return field;
}


Update:
The BoundField object formats values differently depending on html encoding. If the html encoding is enabled, then the value is transformed into a string, then the formatting is applied. That means that number formatting will NOT work when html encoding is true.
That is why I've added the field.HtmlEncode=false; line above. A more secure option would be to make the HtmlEncode property depend on the field.DataType.

Update2:
While this works, I don't recommend doing it like that. I am using it because I have custom user controls that inherit from the GridView and I need to cover the AutoGeneratedColumns=true case. It is much easier to generate your columns yourself from the DataSource using BoundField objects (Or any other DataControlField objects) that you add to the GridView.Columns collection.

GridView Export to Excel Problems

This guy researched why simple methods like export datagrid to Excel don't work with GridViews or other controls. I have also stumbled on this stupid error when trying to use RenderControl to get the output of a UserControl.

Apparently, the entire problem lies with the
Page.VerifyRenderingInServerForm Method
which throws an exception if the page is not currently in the render phase of page processing, and inside the <form runat=server> tags.

Luckily it can be overridden. Here is the bug posting at Microsoft and their suggested solutions. Microsoft removed the page, so I can't show it to you.

This is the actual code for the method in the Page control in NET 2.0. Just override the hell out of it.
public virtual void VerifyRenderingInServerForm(Control control)
{
if (this.Context == null || base.DesignMode) return;

if (control == null)
{
throw new ArgumentNullException("control");
}
if (!this._inOnFormRender && !this.IsCallback)
{
throw new HttpException(System.Web.SR.GetString("ControlRenderedOutsideServerForm", new object[] {
control.ClientID,
control.GetType().Name
}));
}
}

How to include a header on each page when printing a DataGrid - The Code Project - .NET

There is a simple solution for printing tables with repeating headers on each printed page. It involves CSS styling of the THEAD section of a table. Unfortunately, neither DataGrids nor GridViews render the THEAD tag. Somehow, Microsoft seems hellbent against it. So either create a control that renders THEAD, then add "display:table-header-group;" to the THEAD style, or use this Javascript function:



function AddTHEAD(tableName)
{
var table = document.getElementById(tableName);
if(table != null)
{
var head = document.createElement("THEAD");
head.style.display = "table-header-group";
head.appendChild(table.rows[0]);
table.insertBefore(head, table.childNodes[0]);
}
}
Update:
Building a GridView, DataGrid or Table with THEAD, TBODY or TFOOT sections in NET 2.0

Using SQL Server instead of Access files:
1. Run aspnet_regsql.exe (from the NET Framework 2.0 folder)
2. Add to web.config (inside the configuration tag):
<connectionStrings>
<remove name="LocalSqlServer"/>
<add name="LocalSqlServer" connectionString="Data Source=localhost;Initial Catalog=aspnetdb;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
(that's because LocalSqlServer is already defined by default. Really dumb)
3. Go to the Website menu in Visual Studio -> ASP.NET Configuration and create users, roles and access rules.

Logging out programatically:
FormsAuthentication.SignOut();

Changing settings for the membership (in system.web section):
<membership defaultProvider="CustomizedProvider">
<providers>
<remove name="AspNetSqlMembershipProvider"/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="LocalSqlServer"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/"
requiresUniqueEmail="false"
minRequiredPasswordLength="1"
minRequiredNonalphanumericCharacters="0"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""
commentTimeout=""/>
</providers>
</membership>

I somehow managed to add to one of my Visual Studio 2005 Web Projects a webservice that had the code written "inline" meaning the <%@ WebService Language="C#" Class="WService"%> tag, followed by the C# code. While Visual Studio has a decent Intellisense functionality in asmx files, ReSharper doesn't. So I felt the need to move the code into a codebehind file. You would think that adding the Codebehind="WService.amsx.cs" would be enough. No, it isn't! As the codebehind model for VS is to have the codebehind in a compiled dll, an error like "Cannot create type WService" will annoy the hell out of you. The solution is to add the cs file into the App_Code directory.
<%@ WebService Language="C#" Class="WService" Codebehind="~/App_Code/WService.asmx.cs"%>

I've tried compiling and using a dll from the net for a Pocket PC and, even if the compilation of the source worked, when trying to add it as a reference, I got an error and the dll would not show in the references. However, a lot of other errors occurred later on, as if the dll was still referenced. Reading the csdproj file directly, I noticed that the reference to the dll was there, but that every time the project was loaded, the same error occurred and the reference did not show. The only solution is to remove with a text editor the XML entry from the csdproj file.

Also, VS2003 hangs periodically after a few debug-deploy cycles, usually when trying to stop debugging, using 100% CPU and freezing. This might also be related with version 2.0 of ReSharper which I have installed, but somehow I doubt it, cause I love the guys at JetBrains! :) The only solution is to kill the process, which will close VS2003, then restart it and reload the project.

Another issue is with the file on the Palm being in use while you try to deploy. The solution is to get to the Palm Control Panel, go to Memory, select the Running Programs, kill any program that has the same name as the program you want to deploy and anything that looks like "Client".

There are other issues, but I don't care to remember them all B-)

How to: Reference ASP.NET Master Page Content:
You must use a MasterType tag in each page to define the exact master page used. After that, all public members and properties in the MasterPage will be available in code as
Master.PropertyOrMember="RightHand";

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.

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.

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

One of the major marketing statements regarding ASP.NET was its capability to display content differently depending on browser. What actually happends, though, is that Internet Explorer is considered a HTML 4.0 compatible browser, while others are not. If you ever looked at a normal page with a few textboxes and a button on Firefox or Netscape, then you know what I mean.

Example:rendering for FireFox:

<table width="30%" border="2">
<tr>
<td align="Right">
<span >
Hi there...
</span>
</td>
</tr>
</table>


rendering for IE:

<table width="30%" border="2">
<tbody><tr>
<td style="FONT-SIZE: large; COLOR: red" align="right">
Hi there...
</td>
</tr>
</tbody></table>


In this case, if you want to , let's say, replace the innerHTML property of the td, then you lose the color red.Other such changes put the width/height parameters inside the style property or outside it.

Apparently, the difference in rendering comes from the HtmlTextWriter class. For "not compatible browsers" an overridden class is used for rendering: Html32TextWriter.

How to fix it.
The recomended fix for this is change the tag in machine.config. That would make your server compatible to each browser as you see fit. The downside of this, of course, is that your ASP.NET application will render differently for each hosting server making it undeployable.

My fix.
Just inherit the Page class and add this:
protected override void Render(HtmlTextWriter writer)
{
writer=new HtmlTextWriter(writer.InnerWriter);
base.Render (writer); // or your own rendering logic
}
and use this page class for all forms.

This will make all controls on the page render for HTML4.0 compatible browsers. In my personal opinion, we will never make sites that are designed to be seen with Internet Explorer 3.2 or Nescape 4 so this will work. Of course, that doesn't make the pages look the same on all browsers. One needs to check out all the details regarding browser compatibilty such as the way the Visual Studio IDE adds or removes DOM incompatible attributes, but it's a major step forwards.