Navigation

Search

Categories

On this page

Getting Acquainted With jQuery
Problems With Windows Live Writer and DasBlog
Highlighting Background Color in Gridview With a Checkbox
Building Custom Controls
Getting the ID value of the most recently added record
Remote Desktop Control Software
Disabling a Rogue Web Part
Exporting Data from a Gridview to Excel

Archive

Blogroll

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 130
This Year: 1
This Month: 1
This Week: 0
Comments: 0

Sign In

 Tuesday, September 30, 2008
Tuesday, September 30, 2008 2:47:55 PM (Eastern Standard Time, UTC-05:00) ( )

I've been trying to get up to speed using jQuery especially since Microsoft made the announcement that jQuery will be bundled with Visual Studio in the near future.  I'm going to use this post to compile some links related to jQuery.

Tuesday, September 30, 2008 1:58:57 PM (Eastern Standard Time, UTC-05:00) ( )

I love Live Writer for posting content to my blog (DasBlog I'm not so thrilled with). Occasionally, Live Writer will stop posting content to the site - I receive no error messages at all; it just won't post.  I've discovered that Live Writer creates a folder under /dasblog/content/binary/WindowsLiveWriter/<title of blog post>/ when it encounters a problem. Deleting this folder seems to fix the problem.

Tuesday, September 30, 2008 1:51:07 PM (Eastern Standard Time, UTC-05:00) ( )

<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> <script language="javascript" type="text/javascript"> function changeColor(obj) { var rowObject = getParentRow(obj); if(obj.checked) { rowObject.style.backgroundColor = 'Yellow'; } else { rowObject.style.backgroundColor = ''; } } // This method returns the parent row of the object function getParentRow(obj) { do { if(isFireFox()) { obj = obj.parentNode; } else { obj = obj.parentElement; } } while(obj.tagName != "TR") return obj; } function isFireFox() { return navigator.appName == "Netscape"; } </script> </head> <body> <form id="form1" runat="server"> <asp:AccessDataSource ID="AccessDataSource1" runat="server" DataFile="~/App_Data/email.mdb" SelectCommand="SELECT [Name], [Email] FROM [tblEmail]"> </asp:AccessDataSource> <div> <asp:GridView runat="server" ID="gvFulfillment" AutoGenerateColumns="False" DataSourceID="AccessDataSource1"> <Columns> <asp:TemplateField HeaderText="Select:"> <ItemTemplate> <asp:CheckBox ID="chkSelect" runat="server" onClick="changeColor(this)" /> </ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" /> <asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" /> </Columns> <HeaderStyle CssClass="contentGridHeader" HorizontalAlign="center" /> <RowStyle CssClass="content" /> <SelectedRowStyle CssClass="contentGridSelected" /> <PagerStyle CssClass="content" /> </asp:GridView> </div> </form> </body> </html>
 Friday, September 26, 2008
Friday, September 26, 2008 1:44:25 PM (Eastern Standard Time, UTC-05:00) ( )


The two basic types of controls are fully rendered and composite controls.  You must start from scratch to build a fully rendered control and a composite control builds upon existing controls.

  • System.Web.UI.Control
  • System.Web.UI.Control.WebControls.WebControl
  • System.Web.UI.Control.WebControls.CompositeControl

For example, the CompositeControl class inherits from the WebControl class, which inherits from the Control class. Each of these classes add additional functionality. The base class for all controls in the ASP.NET framework is the System.Web.UI.Control class. Every control ultimately derives from this control. The System.Web.UI.Control.UI.WebControls.CompositeControl class should be used as the base class for any composite control.

All Web controls inherit from the base System.Web.UI.WebControls.WebControl class. 

This is an example of a fully rendered control.  When creating these you take on the responsibility of specifying all of the HTML content that the control renders to the browser. This example derives from the base Control class

** FullyRenderedControl.vb **

Imports System.Web.UI
 
Namespace myControls
    Public Class FullyRenderedControl
     Inherits Control
        Private _Text As String
 
        Public Property Text() As String
            Get 
                 Return _Text
            End Get
            Set (ByVal Value As String) 
                 _Text = value
            End Set
        End Property
 
        Protected Overrides  Sub Render(ByVal writer As HtmlTextWriter)
            writer.Write(_Text)
        End Sub
    End Class
End Namespace

** ShowFullyRenderedControl.aspx ** and demo

<%@ Page Language="VB" %>
<%@ Register TagPrefix="custom" Namespace="myControls" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Show Fully Rendered Control</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
    <custom:FullyRenderedControl
        ID="FullyRenderedControl1"
        Text="Hello World!" 
        runat="Server" />
    
    </div>
    </form>
</body>
</html>

In the next example, rather than inherit from the base Control class, you can create a fully rendered control by inheriting a new control from the base WebControl class. When inheriting from the WebControl class, you override the RenderContents() method instead of the Render() method.  Notice that the BackColor, BorderStyle, and Font properties are set because it derives from the base WebControl class.

** FullyRenderedWebControl.vb **

Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace myControls
    Public Class FullyRenderedWebControl
        Inherits WebControl

        Private _Text As String

        Public Property Text() As String
            Get
                Return _Text
            End Get
            Set(ByVal Value As String)
                _Text = value
            End Set
        End Property

        Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
            writer.Write(_Text)
        End Sub

    End Class
End Namespace

** ShowFullyRenderedWebControl.aspx ** and demo

<%@ Page Language="VB" %>
<%@ Register TagPrefix="custom" Namespace="myControls" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Show Fully Rendered WebControl</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
    <custom:FullyRenderedWebControl
        ID="FullyrenderedWebControl1"
        Text="Hello World"
        BackColor="Yellow"
        BorderStyle="Dashed" 
        Font-Size="32px"   
        Runat="Server" />
    
    </div>
    </form>
</body>
</html>

A WebControl, unlike a control, renders an enclosing <span> tag by default.

<span id="FullyrenderedWebControl1" style="display:inline-block;background-color:Yellow;border-style:Dashed;font-size:32px;">Hello World</span>

You can specify a different tag by overriding the WebControl's TagKey property. This control renders its contents within an HTML <div> tag.

** Glow.vb **

Imports System.Web.UI
Imports System.Web.UI.WebControls 

Namespace myControls
    Public Class Glow
        Inherits WebControl
        Private _Text As String 

        Public Property Text() As String
            Get
                Return _Text
            End Get
            Set(ByVal Value As String)
                _Text = value
            End Set
        End Property 

        Protected Overrides ReadOnly Property TagKey() As HtmlTextWriterTag
            Get
                Return HtmlTextWriterTag.Div
            End Get
        End Property 

        Protected Overrides Sub AddAttributesToRender(ByVal writer As HtmlTextWriter)
            writer.AddStyleAttribute(HtmlTextWriterStyle.Filter, "glow(Color=#ffd700,Strength=10)")
            MyBase.AddAttributesToRender(writer)
        End Sub 

        Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
            writer.Write(_Text)
        End Sub 

        Public Sub New()
            Me.Width = Unit.Parse("500px")
        End Sub 

    End Class
End Namespace

** ShowGlowWebControl.aspx ** and demo
<%@ Page Language="VB" %>
<%@ Register TagPrefix="custom" Namespace="myControls" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Show Fully Rendered WebControl</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>    
    <custom:Glow
        ID="FullyGlowControl"
        Text="Hello World"
        Font-Size="32px"   
        Runat="Server" />
    
    </div>
    </form>
</body>
</html>
 Friday, September 19, 2008
Friday, September 19, 2008 3:52:16 PM (Eastern Standard Time, UTC-05:00) (  |  )


The built-in functions @@Identity() and Scope_Identity() are designed to retrieve the most recently added record's autoincrement identity value from Access and Sql Server respectively. Here are some usage examples.

Access and @@Identity()

The Jet 4.0 provider supports @@Identity(), which means that developers no longer need to use Select Max(ID) or some other method. The key to @@Identity is that it returns the value of an autoincrement column that is generated on the same connection.

This last bit is important, because it means that the Connection object used for the Insert query must be re-used without closing it and opening it up again. Access doesn't support batch statements, so each must be run separately. It is also therefore possible, though not necessary, to create a new Command object to run the Select @@Identity query. The following code shows this in action where the Connection object is opened, then the first query is executed against cmd, followed by changing the CommandText property of cmd to "Select @@Identity" and running that.

Dim query As String = "Insert Into Categories (CategoryName) Values (?)"
Dim query2 As String = "Select @@Identity"
Dim ID As Integer
Dim connect As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
    "Data Source=|DataDirectory|Northwind.mdb"
Using conn As New OleDbConnection(connect)
  Using cmd As New OleDbCommand(query, conn)
    cmd.Parameters.AddWithValue("", Category.Text)
    conn.Open()
    cmd.ExecuteNonQuery()
    cmd.CommandText = query2
    ID = cmd.ExecuteScalar()
  End Using
End Using

SQL Server and Scope_Identity()

While Sql Server also supports @@Identity(), the recommended method for obtaining identity values on this platform is Scope_Identity(),

Dim query As String = "Insert Into Categories (CategoryName) Values (@CategoryName);" & _
    "Select Scope_Identity()"
Dim ID As Integer
Dim connect As String = "Server=.\SQLExpress;AttachDbFilename=|DataDirectory|Northwind.mdf;" & _
    "Database=Northwind;Trusted_Connection=Yes;"
Using conn As New SqlConnection(connect)
  Using cmd As New SqlCommand(query, conn)
    cmd.Parameters.AddWithValue("@CategoryName", Category.Text)
    conn.Open()
    ID = cmd.ExecuteScalar()
  End Using
End Using

Alternatively, you may prefer to use an output parameter from a stored procedure, and ExecuteNonQuery().

Dim query As String = "AddCategory"
Dim ID As Integer
Dim connect As String = "Server=.\SQLExpress;Database=Northwind;Trusted_Connection=Yes;"
Using conn As New SqlConnection(connect)
  Using cmd As New SqlCommand(query, conn)
    cmd.CommandType = CommandType.StoredProcedure
    cmd.Parameters.AddWithValue("@Category", Category.Text)
    cmd.Parameters.Add("@CategoryID", SqlDbType.Int, 0, "CategoryID")
    cmd.Parameters("@CategoryID").Direction = ParameterDirection.Output
    conn.Open()
    cmd.ExecuteNonQuery()
    ID = cmd.Parameters("@CategoryID").Value
  End Using
End Using
CREATE PROCEDURE AddCategory
  -- Add the parameters for the stored procedure here
  @Category nvarchar(15),
  @CategoryID int OUTPUT
AS
BEGIN
  SET NOCOUNT ON;

  -- Insert statements for procedure here
  Insert Into Categories (CategoryName) Values (@Category)
  Set @CategoryID = Scope_Identity()
END

Finally, you can create a stored procedure that contains no output parameter, but ends with 'Select Scope_Identity()'. This version requires ExecuteScalar(), and requires less ADO.NET code and a shorter Stored Procedure.

Dim query As String = "AddCategory"
Dim ID As Integer
Dim connect As String = "Server=.\SQLExpress;Database=Northwind;Trusted_Connection=Yes;"
Using conn As New SqlConnection(connect)
  Using cmd As New SqlCommand(query, conn)
    cmd.CommandType = CommandType.StoredProcedure
    cmd.Parameters.AddWithValue("@Category", Category.Text)
    conn.Open()
    ID = cmd.ExecuteScalar()
  End Using
End Using

The stored procedure:

CREATE PROCEDURE AddCategory
  -- Add the parameters for the stored procedure here
  @Category nvarchar(15)
AS
BEGIN
  SET NOCOUNT ON;

  -- Insert statements for procedure here
  Insert Into Categories (CategoryName) Values (@Category)
  Select Scope_Identity()
END
Friday, September 19, 2008 2:17:13 PM (Eastern Standard Time, UTC-05:00) ( )


I've used different software applications over the years to control another machine remotely like pcAnywhere, Windows Remote Desktop, Live Meeting, VNC etc. but with all of these the machine you are trying to log into has to install some client software or I run into firewall issues. One product recommended by Scott Mitchell on his blog is copilot from Frog Creek Software.  It's been very helpful helping clients and family with their random computer problems.

 Tuesday, September 16, 2008
Tuesday, September 16, 2008 8:54:26 AM (Eastern Standard Time, UTC-05:00) ( )

Sometimes when adding custom Web parts to a Sharepoint site, a script or code error will cause the whole page to become disabled and you cannot edit or remove the offending Web part. Fortunately, there is a little trick you can use to get around this.  The trick is to add Contents=1 to the URL string which will bring up the Web Parts Page Maintenance page.  For example, typing in http://myserver/default.aspx?Contents=1 will display

From this page you can then choose the bad Web part and delete it.

 Tuesday, September 09, 2008
Tuesday, September 09, 2008 8:34:31 AM (Eastern Standard Time, UTC-05:00) (  |  )

I've done this many times in the past with other applications using the code below but once I moved the application into a Sharepoint environment coupled with AJAX extensions, I kept receiving the dreaded "RegisterForEventValidation can only be called during Render" error message. 

 

Sub ExcelExport(ByVal Source As Object, ByVal E As EventArgs)                    
            MyGrid.AllowPaging = "False"
            MyGrid.AllowSorting = "False"
            Dim tw As New StringWriter()
            Dim hw As New System.Web.UI.HtmlTextWriter(tw)
            Dim frm As HtmlForm = New HtmlForm()
            Response.ContentType = "application/vnd.ms-excel"
            Response.AddHeader("content-disposition", "attachment;filename=IT.Work.Requests.xls")
            Response.Charset = ""
            EnableViewState = False
            Controls.Add(frm)
            frm.Controls.Add(MyGrid)
            frm.RenderControl(hw)
            Response.Write(tw.ToString())
            Response.End()
            MyGrid.AllowPaging = "True"
            MyGrid.DataBind()
    End Sub

The most common fix for this problem is to set EnableEventValidation="false" in the page directive but this wasn't working for me either. 

Another common suggestion is to use the VerifyRenderingInServerForm method which ensures than a Htmlform control is rendered at the runtime.


Public
Overloads Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
End Sub 


Finally, which ultimately fixed the problem was Matt Berseth's blog post on exporting data from a gridview to Excel.  The VB version of the code is below.

** Default.aspx **

<%@ Page Language="VB" AutoEventWireup="true"  CodeFile="Default.aspx.vb" Inherits="_Default" %>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:SqlDataSource 
                ID="sqldsCustomers" runat="server" 
                SelectCommand="select * from dbo.customers" SelectCommandType="Text" 
                ConnectionString="server=PCFRED\SQLEXPRESS;database=northwind;Trusted_Connection=yes;" /> 
            
            <asp:GridView 
                id="gvCustomers" runat="server" 
                AllowPaging="true" AllowSorting="true" PageSize="10" DataSourceID="sqldsCustomers" />
            <asp:Button 
                ID="btnExportGrid" runat="server" 
                Text="Export to Excel" OnClick="BtnExportGrid_Click" />
        </div>
    </form>
</body>
</html>

** Default.aspx.vb **

Imports System
Imports System.Data
Imports System.Configuration
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls

Public Class _Default
    Inherits System.Web.UI.Page
    
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
        
    End Sub
    
    Protected Sub BtnExportGrid_Click(ByVal sender As Object, ByVal args As EventArgs)
        '  pass the grid that for exporting ...
        GridViewExportUtil.Export("Customers.xls", Me.gvCustomers)
    End Sub
End Class

** App_Code/GridviewExportUtil.vb **

Imports System
Imports System.Data
Imports System.Configuration
Imports System.IO
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls

Public Class GridViewExportUtil

    Public Shared Sub Export(ByVal fileName As String, ByVal gv As GridView)
        HttpContext.Current.Response.Clear()
        HttpContext.Current.Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", fileName))
        HttpContext.Current.Response.ContentType = "application/ms-excel"
        Dim sw As StringWriter = New StringWriter
        Dim htw As HtmlTextWriter = New HtmlTextWriter(sw)
        '  Create a form to contain the grid
        Dim table As Table = New Table
        table.GridLines = gv.GridLines
        '  add the header row to the table
        If (Not (gv.HeaderRow) Is Nothing) Then
            GridViewExportUtil.PrepareControlForExport(gv.HeaderRow)
            table.Rows.Add(gv.HeaderRow)
        End If
        '  add each of the data rows to the table
        For Each row As GridViewRow In gv.Rows
            GridViewExportUtil.PrepareControlForExport(row)
            table.Rows.Add(row)
        Next
        '  add the footer row to the table
        If (Not (gv.FooterRow) Is Nothing) Then
            GridViewExportUtil.PrepareControlForExport(gv.FooterRow)
            table.Rows.Add(gv.FooterRow)
        End If
        '  render the table into the htmlwriter
        table.RenderControl(htw)
        '  render the htmlwriter into the response
        HttpContext.Current.Response.Write(sw.ToString)
        HttpContext.Current.Response.End()
    End Sub

    ' Replace any of the contained controls with literals
    Private Shared Sub PrepareControlForExport(ByVal control As Control)
        Dim i As Integer = 0
        Do While (i < control.Controls.Count)
            Dim current As Control = control.Controls(i)
            If (TypeOf current Is LinkButton) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, LinkButton).Text))
            ElseIf (TypeOf current Is ImageButton) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, ImageButton).AlternateText))
            ElseIf (TypeOf current Is HyperLink) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, HyperLink).Text))
            ElseIf (TypeOf current Is DropDownList) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, DropDownList).SelectedItem.Text))
            ElseIf (TypeOf current Is CheckBox) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, CheckBox).Checked))
                'TODO: Warning!!!, inline IF is not supported ?
            End If
            If current.HasControls Then
                GridViewExportUtil.PrepareControlForExport(current)
            End If
            i = (i + 1)
        Loop
    End Sub
End Class