Disable ASP.NET Form Button

When providing buttons on a web page, we may wish to show a particular button as ‘greyed out’, signifying that it is more generally available for use, but not for the task we are undertaking.

An example of this would be an edit button.

If the content we are adding (perhaps the details for a user) is new then it would be inappropriate to be able to click on a button to edit the details.

In this example the editor used is Visual Studio as a part of a DotNetNuke module. The file edited is the presentation view, perhaps a file called default.ascx.

To grey the text on a button simply add the word disabled to the button definition.

<input id=”edit” “disabled” type=”submit” value=”Edit” name=”edit”>

It looks strange but I’ve found that the word disabled should be within speech marks.

Formatting Datagrid Data Text Two Ways

Data grid output can be formatted differently for the public/normal view and the edit view.

In this example both methods are used.

Using inline table row editing with a DataGrid I wished to change the formatting according to its state.

To illustrate this I have included below an example template column.

<HEADERSTYLE HorizontalAlign="Center"></HEADERSTYLE>
<asp:Label Text=‘<%# DataBinder.Eval(Container, "DataItem.price", "{0:c}") %>’ runat="server">
<asp:TextBox id="price" Text=‘<%# DataBinder.Eval(Container, "DataItem.price", "{0:N2}") %>’ runat="server" Columns="6">

We are able to format the content of the DataGrid cell by one of two methods, dependent upon whether the column is a bound column or whether it is a template column.

As can be seen two different formatting styles are used.

When the DataGrid is normally viewed the currency format is displayed and when the row is being edited we switch to a 2 decimal place view. To provide the number in a suitable format, without the presentation of the currency symbol. After all a currency symbol within the textbox will give us an extra unnecessary item to handle.

Bound column

For the bound column I’ve added DataFormatString=”{0:N2}%” to the definition of the column.

Looking at the table below, we can see that in our example, we shall format the column to have two digits after the decimal point, followed by a percentage sign.

Template column

For the template column I’ve added the formatting into the reference to the data:

text=‘<%# DataBinder.Eval(Container, “DataItem.Total”, “{0:N2}%”) %>’


The table below summarises the formatting expressions with their results.

{0:C}Currency item based on the locale, For example £29.99
{0:D4}A number of the set number plus 1. For example 00124
{0:N2}%A number with two decimal places, followed by a percentage sign
{0:0.0}A number rounded to one decimal place.
{0:D}The date represented as a long string. For example Monday, 20 July 2004
{0:dd-MM-yy}The number as defined by the day, month and year code. for example 20-07-04

Add Browser Redirection to ASP.NET File

Perhaps a page was created with a spelling error, or a reorganisation of the website means that a particular page has been renamed.

We wish to redirect our visitors to the page to a different address.

In the example below its assumed that the website page has moved to www.example.com/fruit-and-veg/.

We wish to tell the browser to redirect to the new page name by adding a short snippet of code to the page.

<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
Response.Status = "301 Moved Permanently";

The code example above can be added to the page. This is for a dynamic asp.net page. It won’t work for a static HTML page.

In the above I’ve included the notification that the change is permanent.

Browsers will cache the redirect, after all you’ve told the browser that you no longer wish the old page to be visited. You may find forcing browsers to adopt a change back difficult to achieve, with the browser reluctant to discover the change. A further permanent redirect back again may be used.

I’ve illustrated the example using a permanent redirect. But, as noted, it’s possible that the browsers will equally permanently cache your rule. If it’s wrong then amending it may well be ignored. Experiment first with a temporary redirect, just to be safe.

If its your intention to redirect more than the single page, perhaps a whole menu section, by adding the redirect into a common header file then you may wish to reconsider your approach. Making use of the file web.config.

CustomValidator with Client JavaScript

I had crafted a custom validator for an DNN asp.net web page with a function to validate form elements.

Using the DNN pop-up calendar, with appropriate date formatting according to the browser, had issues with visitors not setting the language within the browser correctly. It was also decided that using 3 dropdownlists would provide a better control of the selection, and less issue with date selection on mobile devices using the pop up calendar.

I added 3 drop down lists to a web page to facilitate date selection.

To ensure that the date was valid I created a custom control to be referenced on the page with validateDate()

Initially I found that the function was firing, but that the status wasn’t being returned.

The JavaScript function was amended, requiring both sender and args parameters, like so:

<script type="text/javascript">
function validateDate(sender,args) {
    var ddlDay = $("#<% = ddlTheDay.clientid %>");
    var ddlMonth = $("#<% = ddlTheMonth.clientid %>");
    var ddlYear = $("#<% = ddlTheYear.clientid %>");

    document.getElementById('<% = cvTheDay.clientid %>').style.display = 'none';
    document.getElementById('<% = cvTheMonth.clientid %>').style.display = 'none';
    document.getElementById('<% = cvTheYear.clientid %>').style.display = 'none';

    // check date was selected
    if (ddlDay.val() < 0 ||
        ddlMonth.val() < 0 ||
        ddlYear.val() < 0) { // if ($('.validateDate').hasClass('validDate')){ // $('.validateDate').toggleClass('inValidDate validDate'); //} args.IsValid = false; return false; } // ensure days value correct if (ddlDay.val() > daysInMonth(ddlMonth.val(), ddlYear.val())) {
        args.IsValid = false;
        return false;

    // check date is valid
    var dobDate = new Date(ddlYear.val(), ddlMonth.val() - 1, ddlDay.val());

    if (Object.prototype.toString.call(dobDate) === "[object Date]") {
        if (isNaN(dobDate.getTime())) {
            // date is not valid
            args.IsValid = false;
            return false;
        else {
            // date is valid
            args.IsValid = true;
            return true;
    else {
        // not a date
        args.IsValid = false;
        return false;

function daysInMonth(month, year) {
    return new Date(year, month, 0).getDate();

Shown below are the dropdownlists, together with their custom validators.

<asp:dropdownlist id="ddlTheDay" visible="true" runat="server" name="ddlTheDay" class="ddlTheDay" />
<asp:dropdownlist id="ddlTheMonth" visible="true" runat="server" name="ddlTheMonth" class="ddlTheMonth" />
<asp:dropdownlist id="ddlTheYear" visible="true" runat="server" name="ddlTheYear" class="ddlTheYear" />
<asp:customvalidator id="cvTheDay" runat="server" SetFocusOnError="True"
Display="Dynamic" ErrorMessage="The date is invalid!" ControlToValidate="ddlTheDay" ClientValidationFunction="validateDate" />
<asp:customvalidator id="cvTheMonth" runat="server" SetFocusOnError="True"
Display="Dynamic" ErrorMessage="The date is invalid!" ControlToValidate="ddlTheMonth" ClientValidationFunction="validateDate" />
<asp:customvalidator id="cvTheYear" runat="server" SetFocusOnError="True"
Display="Dynamic" ErrorMessage="The date is invalid!" ControlToValidate="ddlTheYear" ClientValidationFunction="validateDate" />
<div class="validateDate validDate">The date is invalid!</div>

As can be seen above I am using just the one div with the error announcement. Its default setting is within the module’s CSS file module.css, details are below:


A RadioButtonList in a GridView

A GridView is to include a RadioButtonList in its presentation. The options are to be populated as fixed options, not taken from a database.

The example below takes values from the DotNetNuke Lists and displays them as a radio button list.

In the presentation file there is a GridView, called gdvMembership

<asp:GridView ID="gdvMembership" runat="server"
    <asp:TemplateField ItemStyle-HorizontalAlign="left" ItemStyle-Width="80%">
    <asp:RadioButton ID="rbnOptions" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Text")  %>' GroupName='<%# DataBinder.Eval(Container, "DataItem.Value")  %>' Checked='<%# DataBinder.Eval(Container, "DataItem.Selected")  %>' AutoPostBack="true" OnCheckedChanged="setSelection" />

In the code behind, a subroutine is used to populate the GridView and to set the selected item.

Private Sub Registration(ByVal SeclectedValue as string)
  Dim dt as DataTable = new DataTable
  dt.Columns.Add(New DataColumn("Text"))
  dt.Columns.Add(New DataColumn("Value"))
  dt.Columns.Add(New DataColumn("Enabled"))
  Dim row as dataRowrow = dt.newRow()
  row("Text") = "I am registered with the organisation"
  row("Value") = "Registered"
  row("Enabled") = True"
  If SelectedValue Is Nothing Then
    row("Selected") = False
  ElseIf SelectedValue = "Registered" Then
    row("Selected") = True
    row("Selected") = False
  End If
  dt.Rows.Add(row)row = dt.newRow()
  gdvMembership.DataSource = dt
End Sub

Whilst populating the rest of the page content the above sub-routine is called with the value of the registration status.


Radio buttons of a different row in a GridView cannot be grouped together. The issue is caused by each row in the GridView being given a different ident.

The radiobuttons are therefore not of the same name once the page is rendered.

<input id=”dnn_ctr485_application_gdvMembership_rbnOptions_0″ name=”dnn_ctr485_application_gdvMembership_rbnOptions_1″…>

Use the GroupName parameter.

I had considered using JQuery to change uncheck the other options when the selection is changed. However, I chose to use an auto postback and a call to a function: don’t forget to add AutoPostBack=”true”.

Protected Sub setSelection(ByVal sender As Object, ByVal e As System.EventArgs)
  For Each row As GridViewRow In gdvMembership.Rows
    Dim rb As RadioButton = TryCast(row.FindControl("rbnCUOptions"), RadioButton)
    Dim rbn As RadioButton = TryCast(sender, RadioButton)
    If Not rb Is rbn Then
      rb.Checked = False
    End If
End Sub

Determine Subroutine Click Event Trigger

Using one sub-routine to handle more than one link button click event requires determination of which button click triggered the sub-routine.

I had an existing subroutine handling a link button. Examining the entries in a form, updating a database and sending an email. A second button was required on the form which would update the database but not send the email.

Options were:

  1. Clone the sub-routine omitting the email sending
  2. Two subroutines to handle the click events with each calling a common function where the difference between the two actions is to be determined. Or just the common block of code for saving the form values.
  3. One subroutine to handle the two click events with the email sending determined by which link button was clicked.

For a quick solution I chose option 1 – clone the subroutine.

However, with time available later I was interested in implementing option 3 – one subroutine handling two click events with a part of the code in the subroutine determined by which link button triggered the event.

In the code below the two link buttons are declared, followed by an outline subroutine to handle the clicking of the two buttons.

'Declare two link buttons with event handling
Dim WithEvents cmdSave as System.LinkButton
Dim WithEvents cmdAdd as System.LinkButton'Sub routine to handle the clicking of either button.
'Run common block of code in sub routine
'Determine event was triggered and run an optional block
Private Sub cmdLButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSave.Click , cmdAdd.click
  'common block of code here (update database)
  'Code here specific to one item
  If sender = cmdAdd  Then
    'send email to applicant confirming form submission
  End If
  If sender = cmdSave Then
    'send email to applicant confirming form submission
  End If
End Sub

A test is made to determine which of the two link buttons was clicked.

In the example above I have shown each as their own separate if statement. When I developed this further I replaced the if statements with a select.

Shown below is a part of the updated

missing the right buttons/commands, would be better to base this upon the GridView edit/update/delete automation

 <asp:GridView ID="gdvCU" runat="server"
    <asp:TemplateField ItemStyle-HorizontalAlign="left" ItemStyle-Width="80%">
        <asp:RadioButton ID="rbnOption" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Text")  %>' GroupName='<%# DataBinder.Eval(Container, "DataItem.Value")  %>' Checked='<%# DataBinder.Eval(Container, "DataItem.Selected")  %>' AutoPostBack="true" OnCheckedChanged="DeselectSelected" />
    <asp:TemplateField ItemStyle-HorizontalAlign="Left" ItemStyle-Width="20%">
        <asp:LinkButton ID="cmdCU" runat="server" Text="Send" CommandName='<%# DataBinder.Eval(Container, "DataItem.Value") %>' CommandArgument='<%# DataBinder.Eval(Container, "DataItem.Value") %>' CausesValidation="false" Visible='<%# DataBinder.Eval(Container, "DataItem.enabled")  %>'></asp:LinkButton>
        <asp:Label ID="FruitId" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.FruitId") %>' Visible="false"></asp:Label>

The Associated subroutine to handle the above gridview and its submission.

Protected Sub cmdCURegister(ByVal sender As Object, ByVal e As GridViewCommandEventArgs) Handles gdvCU.RowCommand
      Select Case e.CommandName
        Case "Registered"
          'action here if visitor is registered
        Case "NotRegistered"
          'action here if visitor is not registered                      
      End Select
    End If

  Catch exc As Exception 'Module failed to load
    ProcessModuleLoadException(Me, exc)
  End Try
End Sub

What about option 2?

Having satisfied my interest with the common subroutine with a test to determine the source and choose the appropriate action I never implemented option 2.

Converting to and from ASCII with vb.net

The ASCII table is a representation of the Roman characters as numeric values. Given an ASCII value we may wish to convert it to its corresponding character, or indeed back the other way from character to ASCII value.

To convert an integer variable of ASCII value, myASCII, to a string we use:

myString = char(myASCII)

and to convert back the other way, from a character to the ASCII value, we use

myASCII = asc(myString)

For the ASCII table of characters see the article: ASCII Table of Numbers and Characters.

Convert Textbox String to Double

The task is to take user entered textbox content, converting it to a field of type double.

As a part of a form I had a numeric entry field. The string value entered in this textbox to be converted to type double for saving in a database.

The public view of the textbox included the appropriate numeric validation. However, I prefer to test the entered content rather than assuming that this protection will be sufficient.

Given below is the text box definition.

<asp:TextBox is=”price” Visible=”True” runat=”Server />

I found that my old test for reading the value in a textbox and assigning it to a variable of type double had become unreliable.

To ensure the textbox string is correctly converted to a double, set the value to 0 if empty, or if it’s value doesn’t qualify as a double. I used the following:

Dim d as Double
If Double.TryParse(tbxPrice.Text, d) Then
  Price = convert.ToDouble(tbxPrice.Text)
  Price = 0
End If

In the example above I first test to see if the content will convert to type double. If this works then we are good to make the conversion.

If the trial conversion fails then set the value to 0.

Whilst it’s possible to add checks to ensure that field values are of the correct type prior to submission I like to also add a check of the data when handling too. You can’t be too careful.

LinkButton Handles OnClick Equivelent in C#

To handle a Linkbutton onclick in VB.NET the LinkButton is declared and a handler sub declared:

<asp:linkbutton id="cmdAdd" runat="server" ResourceKey="Add" BorderStyle="none" CausesValidation="true" />

Private Sub cmdAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAdd.Click
End Sub

C# doesn’t support the VB.net handles on click, the function is simply declared.

The LinkButton declaration is given below. Unlike vb.net there is no WithEvents part of the declaration.

protected global::System.Web.UI.WebControls.LinButton cmdAdd

Explanations of the above:

  • protected – Used to restrict access to the code to the same class.
  • global – Used to clarify that the object is taken from the global namespace as opposed to the current one.
  • :: – This operator, positioned between two indentifiers, is used to look up an identifier.
  • cmdAdd – name of the LinkButton

Looking in the .ascx presentation file the link button is declared as:

<asp:linkbutton id=”cmdAdd” runat=”server” ResourceKey=”cmdAdd” CausesValidation=”true” />

Begin the OnLoad, and include reference for the LinkButton

protected override void OnLoad(EventArgs e) {
try {
cmdAdd.click += new System.EventHandler(cmdAdd_Click);

Then later in the code there is the cmdAdd_Click function:

private void cmdAdd_Click(System.Object sender, System.EventArgs e) {try {
// actions here for the function


MSDN: global

MSDN: The :: Operator

MSDN: How to: Use the Global Namespace Alias

Add an Edit Button to a DataGrid

The DataGrid configuration includes an editColumn, allowing inline editing of the row.

An edit button can be added to a DataGrid using the editColumn feature.

With the addition of the edit column, links are added to handle the usual actions of edit, update and delete.

Associated with the editColumn components are event handlers in the code behind to handle these actions.

When the DataGrid row is in the default mode the column item shows the word (or button dependant upon link type) Edit.

Clicking on the edit link changes the row into edit mode. Converting items into text boxes and changing the link edit to the two links Update and Delete.

To add an edit Button to a DataGrid add code to the following:.

  • In the DataGrid header
  • In the column definitions of the DataGrid add another column
  • In the code behind add an event handler for the edit button
  • In the code behind add an event handler for the update button
  • In the code behind add an event handler for the cancel button
  • Ensure that the postback is handled correctly

DataGrid Header

To handle the additional edit events details are added to the DataGrid header.

<asp:datagrid id="grdTeam"

Shown below are the column definitions of the DataGrid:

<asp:EditCommandColumn buttontype=”LinkButton” UpdateText=”Update” cancelText=Cancel” EditText=”Edit”></asp:EditCommandColumn>

<asp:datagrid id="grdTeam" Visible="False" GridLines="None" runat="server" AutoGenerateColumns="False"
    cellpadding="4" Borderwidth="0" bordercolor="transparent" width="400px" AllowPaging="True"
    <EditItemStyle BackColor="#eeeeee" />
    <AlternatingItemStyle BackColor="#cccccc" />
    <ItemStyle Font-Size="10px" Font-Names="Verdana" HorizontalAlign="Left" BackColor="WhiteSmoke" />
    <HeaderStyle CssClass="datagridheader" />
    <PagerStyle CssClass="datagridPage" Mode="NumericPages" />
        <asp:TemplateColumn HeaderText="Name">
                <asp:Label runat="server" Visible="true" Text='<%# DataBinder.Eval(Container, "DataItem.name") %>' ID="Name" />
                <asp:Label runat="server" Visible="false" Text='<%# DataBinder.Eval(Container, "DataItem.TeamId") %>' ID="TeamId" />
                <asp:TextBox runat="server" Columns="15" Text='<%# DataBinder.Eval(Container, "DataItem.Name") %>' ID="Name" />
                <asp:Label runat="server" Visible="false" Text='<%# DataBinder.Eval(Container, "DataItem.TeamId") %>' ID="TeamId" />
        <asp:EditCommandColumn Visible="True" ButtonType="LinkButton" UpdateText="Update" CancelText="Cancel" EditText="Edit" />
                <asp:LinkButton runat="server" ID="Delete" Text="Delete" CommandName="Delete" CausesValidation="false" Visible="true" />

Edit button event handler

When the edit button is clicked the row is to change to show the update and cancel options.

The row has an index value given by e.Item.ItemIndex.

The index value is assigned to the DataGrid parameter EditItemIndex.

Having set the index for the edit item the DataGrid is bound once more. This time the selected row will be in edit mode, displaying the update and cancel buttons.

Shown below is the subroutine MyDataGridEdit which is handling these actions.

Sub onEditCommand(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
	grdTeam.EditItemIndex = e.Item.ItemIndex
 Catch exc As Exception 'Module failed to load
	ProcessModuleLoadException(Me, exc)
 End Try
End Sub 'doEditCommand

Delete button event handler

To delete an entry the index reference for the row is passed to a subroutine.

Within the delete subroutine the entry reference ID (TeamId) is obtained from a hidden element within the row.

As can be seen there is a test to ensure that the row isn’t in edit mode.

Sub onDeleteCommand(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
	If grdTeam.EditItemIndex = -1 Then
	   Dim objITeam As New TeamInfo
	   Dim objCTeam As New TeamController
	   objCTeam.DeleteTeam( CType(e.Item.FindControl("TeamId"), Label).Text)
	End If
 Catch exc As Exception 'Module failed to load
	ProcessModuleLoadException(Me, exc)
 End Try
End Sub

Cancel button event handler

If the cancel button is clicked the DataGrid is to revert to the normal view.

In this example the EditItemIndex is effectively unset and the DataGrid once again is rebound using the subroutine BindDataGrid.

Sub onCancelCommand(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
	grdTeam.EditItemIndex = -1
 Catch exc As Exception 'Module failed to load
	ProcessModuleLoadException(Me, exc)
 End Try
End Sub 'doCancelCommand

Code behind update button event handler

If we are in edit mode and the update button is clicked then this entry is to be updated.

The update subroutine is called, in this instance myDataGridUpdate.

In this example the reference id for the data entry has been stored as a hidden entry in the row. The first table cell has been used.

Sub onUpdateCommand(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
	If e.CommandName = "Update" Then
	   Dim objITeam As New TeamInfo
	   Dim objCTeam As New TeamController
	   objITeam.Name = CType(e.Item.FindControl("Name"), TextBox).Text
	   objITeam.TeamId = CType(e.Item.FindControl("TeamId"), Label).Text
	End If
	grdTeam.EditItemIndex = -1
 Catch exc As Exception 'Module failed to load
	ProcessModuleLoadException(Me, exc)
 End Try
End Sub

Below I include

Private Sub BindData()
	Dim objITeam As New TeamInfo
	Dim objCTeam As New TeamController
	grdTeam.DataSource = objCTeam.GetTeamList(ModuleId, PortalId)
	grdTeam.Visible = True
 Catch exc As Exception 'Module failed to load
	ProcessModuleLoadException(Me, exc)
 End Try
End Sub