Visual Basic Q&A

As a software engineer, I focus on .NET, especially asp.net, C#, WCF and so on, and I am also very interested in Search Engine Optimization.

Entries Tagged ‘System’

BUG: “Public Overrides WriteOnly Property…” error when you try to override a Microsoft Visual Basic 6.0 property in Microsoft Visual Basic .NET

Symptoms
You have a Microsoft Visual Basic 6.0 class that has a property with the ByRef parameter. When you inherit the class in Visual Basic .NET and override the property, you receive the following compilation error:

‘Public Overrides WriteOnly Property myProp() As System.IntPtr’ cannot override ‘Public Overridable Overloads WriteOnly Property myProp() As System.IntPtr’ because they differ by their return types.
Resolution
The .NET runtime compares the return types of the parameters in the base class and inherited class property. This comparison returns a difference in the return types while it compares the symbols for System.IntPtr and System.Int16. Two separate symbols represent these internally. This results in an error.

How to use Package and Deployment Wizard installation macros

Symptoms
Installation macros can be used throughout the steps of the Package andDeployment Wizard (PDW) to install files to specific locations. Thisarticle documents the available installation macros and what the macroswill equate to during the installation process.
Resolution
These macros will be used by both Setup.exe and Setup1.exe to install filesto common system directories. These macros may be modified after thedistribution set has been created by modifying the Setup.lst file createdby the PDW. See the REFERENCES section of this article for additional information regarding Setup1 files and Bootstrap files.
$(WinSysPath)
This macro installs files to the System subdirectory under the Windowsdirectory. The paths below are typical paths to the Windows\Systemdirectory. This macro can be used for both Setup1 Files and BootstrapFiles.

\Windows\System (Windows 95 or later)\Winnt\System32 (Windows NT 4.0 and later)
$(WinSysPathSysFile)
This macro installs files to the System subdirectory as well, but thefile is installed as a shared component and is not removed when theapplication is removed. The paths below are typical paths to theWindows\System directory. This macro can be used for both Setup1 Filesand Bootstrap Files.

\Windows\System (Windows 95 or later)\Winnt\System32 (Windows NT 4.0 and later)
$(WinPath)
This macro installs files to the directory where Windows is installed.The examples below are typical paths to the Windows directory. Thismacro can be used for both Setup1 Files and BootStrap Files.

\Windows (Windows 95 or later)\Winnt (Windows NT)
$(AppPath)
The application directory specified by the user, or the DefaultDir valuespecified in the Setup section. Valid only for Setup1 Files.
\path
A hard coded path, for example, “c:\mydir”. This is only available bymodifying the Setup.lst file. Valid only for Setup1 Files.$(CommonFiles)
This macro installs files to the Program Files\Common Files folder.Valid only for Setup1 Files.

\Program Files\Common Files\
$(CommonFilesSys)
Installs files to the \System folder under Program Files\Common Files.Valid only for Setup1 Files.

\Program Files\Common Files\System
$(ProgramFiles)
Installs files to the \Program Files directory. Valid only for Setup1Files.

\Program Files
$(MSDAOPath)
Installs files to the location stored in the Registry for Data Access(DAO)Components.
$(Font)
Installs to the \Font subdirectory under the Windows directory.

\Windows\Fonts

How to sum the fields in a Windows Forms DataGrid control and then display the calculated totals in a footer by using Visual Basic .NET

Symptoms
To sum the fields in a Microsoft Windows Forms DataGrid control and then to display the calculated totals in a footer, you must first create a user control that inherits from the System.Windows.Forms.DataGrid class. Then you must handle the events that are raised when a cell in this user control is changed.
You must disable the default sorting feature of the DataGrid control to prevent the footer row from being sorted. To implement custom sorting for your DataGrid control, you must handle the MouseDown event.
You must also disable the footer row of the DataGrid control to prevent users from editing the cells of the footer row. To provide data for the event that prevents users from editing the cells of the DataGrid control, you must define an event arguments class, and then you must define a class that contains methods to paint and to disable the footer row.
To sum the fields and to display the calculated totals in a footer, build the DataGrid control, add an instance of the DataGrid control to a Windows Application project, bind the DataGrid control to the related data, and then build and run the application.
Resolution
This step-by-step article describes how to sum the fields in a Windows Forms DataGrid control by using Microsoft Visual Basic .NET. This article also describes how to customize the Windows Forms DataGrid control to display the calculated totals in a footer.

RequirementsThis article assumes that you are familiar with the following topics: The Windows Forms DataGrid controlData binding by using Windows Forms and Microsoft ADO.NETHandling and raising events
The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:Microsoft Windows 2000, Microsoft Windows XP, or Microsoft Windows Server 2003Microsoft Visual Studio .NET
Create a Windows Control Library projectStart Visual Studio .NET.On the File menu, point to New, and then click Project. The New Project dialog box appears.Under Project Types, click Visual Basic Projects.Under Templates, click Windows Control Library.In the Name box, type DataGridControl, and then click OK. By default, a user control that is named UserControl1 is created.On the View menu, click Solution Explorer.In Solution Explorer, right-click UserControl1.vb, and then click Rename.Rename the UserControl1.vb file as DataGridControlVB.vb.
Inherit from the Windows Forms DataGrid control, and then add variables, properties, and methodsIn Solution Explorer, right-click DataGridControlVB.vb, and then click View Code.Import the required namespaces, and then declare a delegate for the event that disables the cells of the DataGrid control. To do this, add the following code at the top of the code window:

Imports SystemImports System.CollectionsImports System.ComponentModelImports System.DrawingImports System.DataImports System.Data.SqlClientImports System.Windows.FormsImports System.Text’ Declare a delegate for the event that disables the cells of the DataGrid control.Public Delegate Sub DataGridDisableCellEventHandler _(ByVal sender As System.Object, ByVal e As DataGridDisableCellEventArgs)Locate the following code:

Public Class UserControl1Inherits System.Windows.Forms.UserControlMake your Windows Forms DataGrid control inherit from the System.Windows.Forms.DataGrid class. To do this, replace the code that you located in step 3 with the following code:

Public Class DataGridControlVBInherits System.Windows.Forms.DataGridAdd the following variable declarations after the code that you added in step 4:

‘ Declare private variables for your DataGrid control.Private RowCount As IntegerPrivate ColCount As IntegerPrivate SortedColNum As IntegerPrivate Ascending As BooleanPrivate CellValueChanged As BooleanPrivate SourceTable As StringPrivate MyDataView As DataViewPrivate MyDataSet As DataSetPrivate MyDataRow As DataRowPrivate SummaryCols As ArrayListPrivate CurrentDataGridCellLocation As DataGridCellPrivate WithEvents MyDataTable As DataTablePrivate Shared FooterBackColor As BrushPrivate Shared FooterForeColor As BrushLocate the following code comment in the “Windows Form Designer generated code” area:

‘Add any initialization after the InitializeComponent() callPerform custom initialization in the constructor of your Windows Forms DataGrid control. To do this, replace the code comment that you located in step 6 with the following code:

RowCount = 0ColCount = 0CellValueChanged = FalseAscending = FalseMyDataRow = NothingMyDataTable = New DataTable(“NewTable”)CurrentDataGridCellLocation = New DataGridCellSummaryCols = New ArrayListLocate the following code:

#End RegionAdd the following property definitions after the code that you located in step 8:

Public WriteOnly Property GridDataSet() As DataSetSet(ByVal Value As DataSet)MyDataSet = ValueEnd SetEnd PropertyPublic Property SummaryColumns() As ArrayListGetReturn SummaryColsEnd GetSet(ByVal Value As ArrayList)SummaryCols = ValueEnd SetEnd PropertyPublic Property DataSourceTable() As StringGetReturn SourceTableEnd GetSet(ByVal Value As String)SourceTable = ValueEnd SetEnd PropertyPublic Shared Property FooterColor() As BrushGetReturn FooterBackColorEnd GetSet(ByVal Value As Brush)FooterBackColor = ValueEnd SetEnd PropertyPublic Shared Property FooterFontColor() As BrushGetReturn FooterForeColorEnd GetSet(ByVal Value As Brush)FooterForeColor = ValueEnd SetEnd PropertyDisable the default sorting feature of the DataGrid control to prevent the footer row from being sorted. To do this, and to bind the custom DataGrid control to the related data, add the following code after the code that you added in step 9:

Public Sub BindDataGrid()MyDataTable = MyDataSet.Tables(0)MyDataView = MyDataTable.DefaultViewMe.DataSource = MyDataViewDim TableStyle As DataGridTableStyle = New DataGridTableStyleTableStyle.MappingName = SourceTable’ Add a Boolean data type column to the DataTable object.’ You can use this column during your custom sorting.MyDataTable.Columns.Add(“ID”, System.Type.GetType(“System.Boolean”))MyDataTable.Columns(“ID”).DefaultValue = FalseMyDataTable.Columns(“ID”).ColumnMapping = MappingType.HiddenColCount = MyDataTable.Columns.Count’ Create a footer row for the DataTable object.MyDataRow = MyDataTable.NewRow()’ Set the footer value as an empty string for all columns that contains string values.Dim MyIterator As IntegerFor MyIterator = 0 To ColCount – 1If (MyDataTable.Columns(MyIterator).DataType.ToString() = “System.String”) ThenMyDataRow(MyIterator) = “”End IfNext’ Add the footer row to the DataTable object.MyDataTable.Rows.Add(MyDataRow)RowCount = MyDataTable.Rows.Count’ Add a MyDataGridTextBox control to each cell of the DataGrid control.Dim TempDataGridTextBox As MyDataGridTextBoxFor MyIterator = 0 To ColCount – 2TempDataGridTextBox = New MyDataGridTextBox(MyIterator)TempDataGridTextBox.HeaderText = MyDataTable.Columns(MyIterator).ColumnNameTempDataGridTextBox.MappingName = MyDataTable.Columns(MyIterator).ColumnNameAddHandler TempDataGridTextBox.DataGridDisableCell, _New DataGridDisableCellEventHandler(AddressOf SetEnableValues)’ Disable the default sorting feature of the DataGrid control.TableStyle.AllowSorting = FalseTableStyle.GridColumnStyles.Add(TempDataGridTextBox)NextMe.TableStyles.Add(TableStyle)Me.DataSource = MyDataViewMyDataView.ApplyDefaultSort = FalseMyDataView.AllowNew = False’ Set the value of the footer cell.Dim MyCell As DataGridCell = New DataGridCellMyCell.RowNumber = MyDataTable.Rows.Count – 1′ Calculate the value for each of the cells in the footer.Dim MyArray(2) As StringDim MyString As StringFor Each MyString In SummaryColsMyArray = MyString.Split(“,”c)MyCell.ColumnNumber = Convert.ToInt32(MyArray(0))Me(MyCell) = MyDataTable.Compute(MyArray(1), “ID is null”).ToString()NextEnd Sub
Handle the events that are raised when a cell in the DataGrid control is changedYou must handle the ColumnChanged event of the DataTable object, and then you must handle the CurrentCellChanged event of the DataGrid control to track when a cell value in the DataGrid control is changed. To do this, follow these steps: Handle the ColumnChanged event of the DataTable object. To do this, add the following code after the code that you added in step 10 of the “Inherit from the Windows Forms DataGrid control, and then add variables, properties, and methods” section:

‘ Handle the DataTable object’s ColumnChanged event’ to track whether the value in a cell has changed.Private Sub MyDataTable_ColumnChanged(ByVal sender As Object, _ByVal e As System.Data.DataColumnChangeEventArgs) Handles MyDataTable.ColumnChangedDim Row As Integer, Col As IntegerRow = 0Col = 0′ Determine the row that contains the changed cell.Dim TempDataRow As DataRowFor Each TempDataRow In MyDataTable.RowsIf (TempDataRow.Equals(e.Row)) ThenCurrentDataGridCellLocation.RowNumber = RowCellValueChanged = TrueExit ForRow = Row + 1End IfNext’ Determine the column that contains the changed cell.Dim TempDataColumn As DataColumnFor Each TempDataColumn In MyDataTable.ColumnsIf (TempDataColumn.Equals(e.Column)) ThenCurrentDataGridCellLocation.ColumnNumber = ColCellValueChanged = TrueExit ForCol = Col + 1End IfNextEnd SubHandle the CurrentCellChanged event of the DataGrid control. To do this, add the following code after the code that you added in step 1:

‘ Handle the CurrentCellChanged event of the DataGrid control.Private Sub DataGridControlVB_CurrentCellChanged(ByVal sender As Object, _ByVal e As System.EventArgs) Handles MyBase.CurrentCellChangedIf (CellValueChanged = True) ThenDim MyCell As DataGridCell = New DataGridCellMyCell.RowNumber = MyDataTable.Rows.Count – 1′ Calculate the value for each cell in the footer.Dim MyArray(2) As StringDim MyString As StringFor Each MyString In SummaryColsMyArray = MyString.Split(“,”)MyCell.ColumnNumber = Convert.ToInt32(MyArray(0))Me(MyCell) = MyDataTable.Compute(MyArray(1), “ID is null”).ToString()NextEnd IfCellValueChanged = FalseEnd Sub
Handle the MouseDown event of the DataGrid control to implement custom sortingBecause you have disabled the default sorting feature of the DataGrid control, you must perform custom sorting when a user clicks a column header. You must handle the MouseDown event of the DataGrid control to implement custom sorting.
To do this, add the following event handler after the code that you added in step 2 of the “Handle the events that are raised when a cell in the DataGrid control is changed” section:

‘ Handle the MouseDown event to perform custom sorting.Private Sub DataGridControlVB_MouseDown(ByVal sender As Object, _ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDownDim MyHitTestInfo As DataGrid.HitTestInfoMyHitTestInfo = Me.HitTest(e.X, e.Y)Dim ColName As StringIf (MyHitTestInfo.Type = DataGrid.HitTestType.ColumnHeader) ThenDim ColNum As Integer = MyHitTestInfo.ColumnIf (ColNum <> -1) ThenColName = MyDataTable.Columns(ColNum).ColumnName’ Perform custom sorting. To do this, always sort the Boolean data type column in’ ascending order so that the footer row stays at the end.Dim MyChar() As Char = {“↑”c, “↓”c}Dim NewString As String = _Me.TableStyles(0).GridColumnStyles(SortedColNum).HeaderText.TrimEnd(MyChar).Trim()Me.TableStyles(0).GridColumnStyles(SortedColNum).HeaderText = NewStringIf (Ascending = True) ThenMyDataView.Sort = “ID Asc,” + ColName + ” desc”Ascending = FalseMe.TableStyles(0).GridColumnStyles(ColNum).HeaderText = _Me.TableStyles(0).GridColumnStyles(ColNum).HeaderText + ” ↑”SortedColNum = ColNumElseMyDataView.Sort = “ID Asc,” + ColName + ” asc”Ascending = TrueMe.TableStyles(0).GridColumnStyles(ColNum).HeaderText = _Me.TableStyles(0).GridColumnStyles(ColNum).HeaderText + ” ↓”SortedColNum = ColNumEnd IfEnd IfEnd IfEnd Sub
Disable the footer row of the DataGrid controlTo disable the footer row of the DataGrid control, add the following code after the code that you added in the “Handle the MouseDown event of the DataGrid control to implement custom sorting” section:

‘ Disable the footer row of the DataGrid control.Public Sub SetEnableValues(ByVal sender As Object, ByVal e As DataGridDisableCellEventArgs)If (e.Row = RowCount – 1) Thene.EnableValue = FalseElsee.EnableValue = TrueEnd IfEnd Sub
Define an event arguments class that provides data for the DataGridDisableCell eventTo define an event arguments class that provides data for the DataGridDisableCell event, follow these steps: In the Form1.vb file, locate the following code:

End ClassAdd the following code after the code that you located in step 1:

‘ Define a custom event arguments class that inherits from the EventArgs class.Public Class DataGridDisableCellEventArgsInherits EventArgsPrivate MyCol As IntegerPrivate MyRow As IntegerPrivate MyEnableValue As BooleanPublic Sub New(ByVal Row As Integer, ByVal Col As Integer)MyRow = RowMyCol = ColMyEnableValue = TrueEnd SubPublic Property Column() As IntegerGetReturn MyColEnd GetSet(ByVal Value As Integer)MyCol = ValueEnd SetEnd PropertyPublic Property Row() As IntegerGetReturn MyRowEnd GetSet(ByVal Value As Integer)MyRow = ValueEnd SetEnd PropertyPublic Property EnableValue() As BooleanGetReturn MyEnableValueEnd GetSet(ByVal Value As Boolean)MyEnableValue = ValueEnd SetEnd PropertyEnd Class
Define a class that contains methods to paint and to disable the footer rowTo define a class that contains methods to paint and to disable the footer row, add the following code after the code that you added in step 2 of the “Define an event arguments class that provides data for the DataGridDisableCell event” section:

Public Class MyDataGridTextBoxInherits DataGridTextBoxColumn’ Declare an event for the DataGridDisableCellEventHandler delegate that you have defined.Public Event DataGridDisableCell As DataGridDisableCellEventHandlerPrivate MyCol As Integer’ Save the column number of the column to add the MyDataGridTextBox control to.Public Sub New(ByVal Column As Integer)MyCol = ColumnEnd Sub’ Override the Paint method to set colors for the footer row.Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, _ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, _ByVal rowNum As Integer, ByVal backBrush As System.Drawing.Brush, _ByVal foreBrush As System.Drawing.Brush, ByVal alignToRight As Boolean)’ Initialize the event arguments by using the number’ of the current row and the current column.Dim e As New DataGridDisableCellEventArgs(rowNum, MyCol)’ Raise the DataGridDisableCell event.RaiseEvent DataGridDisableCell(Me, e)’ Set the foreground color and the background color for the footer row.If Not e.EnableValue ThenIf DataGridControlVB.FooterColor Is Nothing _Or DataGridControlVB.FooterFontColor Is Nothing ThenbackBrush = Brushes.WhiteforeBrush = Brushes.BlackElsebackBrush = DataGridControlVB.FooterColorforeBrush = DataGridControlVB.FooterFontColorEnd IfEnd If’ Call the Paint event of the DataGridTextBoxColumn class.MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight)End Sub’ Override the Edit method to disable the footer row.Protected Overloads Overrides Sub Edit(ByVal source As System.Windows.Forms.CurrencyManager, _ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal readOnlyFlag As Boolean, _ByVal instantText As String, ByVal cellIsVisible As Boolean)Dim e As DataGridDisableCellEventArgs = Nothing’ Initialize the event arguments by using the number’ of the current row and the current column.e = New DataGridDisableCellEventArgs(rowNum, MyCol)’ Raise the DataGridDisableCell event.RaiseEvent DataGridDisableCell(Me, e)’ Call the Edit event of the DataGridTextBoxColumn’ class for all rows other than the footer row.If e.EnableValue ThenMyBase.Edit(source, rowNum, bounds, readOnlyFlag, instantText, cellIsVisible)End IfEnd SubEnd Class
Save the DataGridControlVB.vb file, and then build the DataGrid controlOn the File menu, click Save DataGridControlVB.vb As. The Save File As dialog box appears.Click the arrow next to the Save button, and then click Save with Encoding. You receive a message to replace the existing DataGridControlVB.vb file.Click Yes. The Advanced Save Options dialog box appears.In the Encoding box, select Unicode (UTF-8 with signature) – Codepage 65001, and then click OK.On the Build menu, click Build DataGridControl to build the DataGridControl.dll assembly.
Create a Windows Application project that uses the DataGrid controlIn Solution Explorer, right-click the DataGridControl solution, point to Add, and then click New Project. The Add New Project dialog box appears.Under Project Types, click Visual Basic Projects.Under Templates, click Windows Application.In the Name box, type TestApplication, and then click OK. By default, a Windows Form that is named Form1 is created.In Solution Explorer, right-click TestApplication, and then click Set as StartUp Project.On the View menu, click Toolbox.Do one of the following, depending on the version of Visual Studio .NET that you have:If you are using Visual Studio .NET 2003, click Add/Remove Toolbox Items on the Tools menu. If you are using Visual Studio .NET 2002, click Customize Toolbox on the Tools menu.The Customize Toolbox dialog box appears.On the .NET Framework Components tab, click Browse. The Open dialog box appears.Locate and then click the DataGridControl.dll assembly that you created in step 5 of the “Save the DataGridControlVB.vb file, and then build the DataGrid control” section.Click Open, and then click OK. The DataGridControlVB control is added to the Toolbox.In the Toolbox, double-click the DataGridControlVB control to add the DataGridControlVB1 control to the Form1 form.Click Form1.On the View menu, click Properties Window to view the Properties window for the Form1 form.Set the Size property to 450, 200.In the Design view of the Form1 form, click the DataGridControlVB1 control.On the View menu, click Properties Window to view the Properties window for the DataGridControlVB1 control.Set the Size property to 420, 115.
Bind the custom DataGrid control to the related dataIn Solution Explorer, right-click Form1.vb, and then click View Code.Import the required namespaces. To do this, add the following code at the top of the code window:

Imports System.DataImports System.Data.SqlClientLocate the following code:

Public Class Form1Inherits System.Windows.Forms.FormAdd the following variable declarations after the code that you located in step 3:

Dim MyConnString As StringDim MyDataSet As DataSet = NothingDim MyDataAdapter As SqlDataAdapter = NothingDim MyConn As SqlConnectionBind the DataGrid control to the related data. To do this, add the following code after the “Windows Form Designer generated code” area.
Note In the following code, replace <ServerName> with the appropriate value for an instance of Microsoft SQL Server:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.LoadDim SqlString As String = “SELECT * FROM discounts”MyConnString = “server=<ServerName>;Integrated Security=SSPI;database=pubs”MyConn = New SqlConnection(MyConnString)MyDataAdapter = New SqlDataAdapter(SqlString, MyConn)MyDataSet = New DataSetTryMyDataAdapter.Fill(MyDataSet, “discounts”)’ Specify the dataset that you want your DataGrid control to use.DataGridControlVB1.GridDataSet = MyDataSet’ Specify the source table that you want your DataGrid control to use.DataGridControlVB1.DataSourceTable = “discounts”‘ Add the columns that you want to sum to an array list. Use the following format:’ “<ColumnNumber>,summing expression”Dim Summary As New ArrayListSummary.Add(“2,sum(lowqty)”)Summary.Add(“3,sum(highqty)”)’ Map the array list to the SummaryColumns property of your DataGrid control.DataGridControlVB1.SummaryColumns = Summary’ Set the foreground color and the background color for the footer row.DataGridControlVB1.FooterColor = Brushes.BlueVioletDataGridControlVB1.FooterFontColor = Brushes.White’ Bind the DataGrid control to the related data.DataGridControlVB1.BindDataGrid()’ Dispose the data adapter, and then close the connection.Catch DatabaseException As SqlExceptionMessageBox.Show(“Database exception: ” & DatabaseException.Message)Catch OtherException As ExceptionMessageBox.Show(OtherException.Message)FinallyMyDataAdapter.Dispose()MyConn.Dispose()End TryEnd Sub
Complete code listingDataGridControlVB.vb

Imports SystemImports System.CollectionsImports System.ComponentModelImports System.DrawingImports System.DataImports System.Data.SqlClientImports System.Windows.FormsImports System.Text’ Declare a delegate for the event that disables the cells of the DataGrid control.Public Delegate Sub DataGridDisableCellEventHandler _(ByVal sender As System.Object, ByVal e As DataGridDisableCellEventArgs)Public Class DataGridControlVBInherits System.Windows.Forms.DataGrid’ Declare private variables for your DataGrid control.Private RowCount As IntegerPrivate ColCount As IntegerPrivate SortedColNum As IntegerPrivate Ascending As BooleanPrivate CellValueChanged As BooleanPrivate SourceTable As StringPrivate MyDataView As DataViewPrivate MyDataSet As DataSetPrivate MyDataRow As DataRowPrivate SummaryCols As ArrayListPrivate CurrentDataGridCellLocation As DataGridCellPrivate WithEvents MyDataTable As DataTablePrivate Shared FooterBackColor As BrushPrivate Shared FooterForeColor As Brush#Region ” Windows Form Designer generated code “Public Sub New()MyBase.New()’This call is required by the Windows Form Designer.InitializeComponent()RowCount = 0ColCount = 0CellValueChanged = FalseAscending = FalseMyDataRow = NothingMyDataTable = New DataTable(“NewTable”)CurrentDataGridCellLocation = New DataGridCellSummaryCols = New ArrayListEnd Sub’UserControl1 overrides dispose to clean up the component list.Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)If disposing ThenIf Not (components Is Nothing) Thencomponents.Dispose()End IfEnd IfMyBase.Dispose(disposing)End Sub’Required by the Windows Form DesignerPrivate components As System.ComponentModel.IContainer’NOTE: The following procedure is required by the Windows Form Designer’It can be modified using the Windows Form Designer.’Do not modify it using the code editor.<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()components = New System.ComponentModel.ContainerEnd Sub#End RegionPublic WriteOnly Property GridDataSet() As DataSetSet(ByVal Value As DataSet)MyDataSet = ValueEnd SetEnd PropertyPublic Property SummaryColumns() As ArrayListGetReturn SummaryColsEnd GetSet(ByVal Value As ArrayList)SummaryCols = ValueEnd SetEnd PropertyPublic Property DataSourceTable() As StringGetReturn SourceTableEnd GetSet(ByVal Value As String)SourceTable = ValueEnd SetEnd PropertyPublic Shared Property FooterColor() As BrushGetReturn FooterBackColorEnd GetSet(ByVal Value As Brush)FooterBackColor = ValueEnd SetEnd PropertyPublic Shared Property FooterFontColor() As BrushGetReturn FooterForeColorEnd GetSet(ByVal Value As Brush)FooterForeColor = ValueEnd SetEnd PropertyPublic Sub BindDataGrid()MyDataTable = MyDataSet.Tables(0)MyDataView = MyDataTable.DefaultViewMe.DataSource = MyDataViewDim TableStyle As DataGridTableStyle = New DataGridTableStyleTableStyle.MappingName = SourceTable’ Add a Boolean data type column to the DataTable object.’ You can use this column during your custom sorting.MyDataTable.Columns.Add(“ID”, System.Type.GetType(“System.Boolean”))MyDataTable.Columns(“ID”).DefaultValue = FalseMyDataTable.Columns(“ID”).ColumnMapping = MappingType.HiddenColCount = MyDataTable.Columns.Count’ Create a footer row for the DataTable object.MyDataRow = MyDataTable.NewRow()’ Set the footer value as an empty string for all columns that contains string values.Dim MyIterator As IntegerFor MyIterator = 0 To ColCount – 1If (MyDataTable.Columns(MyIterator).DataType.ToString() = “System.String”) ThenMyDataRow(MyIterator) = “”End IfNext’ Add the footer row to the DataTable object.MyDataTable.Rows.Add(MyDataRow)RowCount = MyDataTable.Rows.Count’ Add a MyDataGridTextBox control to each cell of the DataGrid control.Dim TempDataGridTextBox As MyDataGridTextBoxFor MyIterator = 0 To ColCount – 2TempDataGridTextBox = New MyDataGridTextBox(MyIterator)TempDataGridTextBox.HeaderText = MyDataTable.Columns(MyIterator).ColumnNameTempDataGridTextBox.MappingName = MyDataTable.Columns(MyIterator).ColumnNameAddHandler TempDataGridTextBox.DataGridDisableCell, _New DataGridDisableCellEventHandler(AddressOf SetEnableValues)’ Disable the default sorting feature of the DataGrid control.TableStyle.AllowSorting = FalseTableStyle.GridColumnStyles.Add(TempDataGridTextBox)NextMe.TableStyles.Add(TableStyle)Me.DataSource = MyDataViewMyDataView.ApplyDefaultSort = FalseMyDataView.AllowNew = False’ Set the value of the footer cell.Dim MyCell As DataGridCell = New DataGridCellMyCell.RowNumber = MyDataTable.Rows.Count – 1′ Calculate the value for each of the cells in the footer.Dim MyArray(2) As StringDim MyString As StringFor Each MyString In SummaryColsMyArray = MyString.Split(“,”c)MyCell.ColumnNumber = Convert.ToInt32(MyArray(0))Me(MyCell) = MyDataTable.Compute(MyArray(1), “ID is null”).ToString()NextEnd Sub’ Handle the DataTable object’s ColumnChanged event’ to track if the value in a cell has changed.Private Sub MyDataTable_ColumnChanged(ByVal sender As Object, _ByVal e As System.Data.DataColumnChangeEventArgs) Handles MyDataTable.ColumnChangedDim Row As Integer, Col As IntegerRow = 0Col = 0′ Determine the row that contains the changed cell.Dim TempDataRow As DataRowFor Each TempDataRow In MyDataTable.RowsIf (TempDataRow.Equals(e.Row)) ThenCurrentDataGridCellLocation.RowNumber = RowCellValueChanged = TrueExit ForRow = Row + 1End IfNext’ Determine the column that contains the changed cell.Dim TempDataColumn As DataColumnFor Each TempDataColumn In MyDataTable.ColumnsIf (TempDataColumn.Equals(e.Column)) ThenCurrentDataGridCellLocation.ColumnNumber = ColCellValueChanged = TrueExit ForCol = Col + 1End IfNextEnd Sub’ Handle the CurrentCellChanged event of the DataGrid control.Private Sub DataGridControlVB_CurrentCellChanged(ByVal sender As Object, _ByVal e As System.EventArgs) Handles MyBase.CurrentCellChangedIf (CellValueChanged = True) ThenDim MyCell As DataGridCell = New DataGridCellMyCell.RowNumber = MyDataTable.Rows.Count – 1′ Calculate the value for each of the cells in the footer.Dim MyArray(2) As StringDim MyString As StringFor Each MyString In SummaryColsMyArray = MyString.Split(“,”)MyCell.ColumnNumber = Convert.ToInt32(MyArray(0))Me(MyCell) = MyDataTable.Compute(MyArray(1), “ID is null”).ToString()NextEnd IfCellValueChanged = FalseEnd Sub’ Handle the MouseDown event to perform custom sorting.Private Sub DataGridControlVB_MouseDown(ByVal sender As Object, _ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDownDim MyHitTestInfo As DataGrid.HitTestInfoMyHitTestInfo = Me.HitTest(e.X, e.Y)Dim ColName As StringIf (MyHitTestInfo.Type = DataGrid.HitTestType.ColumnHeader) ThenDim ColNum As Integer = MyHitTestInfo.ColumnIf (ColNum <> -1) ThenColName = MyDataTable.Columns(ColNum).ColumnName’ Perform custom sorting. To do this, always sort the Boolean data type column in’ ascending order so that the footer row stays at the end.Dim MyChar() As Char = {“↑”c, “↓”c}Dim NewString As String = _Me.TableStyles(0).GridColumnStyles(SortedColNum).HeaderText.TrimEnd(MyChar).Trim()Me.TableStyles(0).GridColumnStyles(SortedColNum).HeaderText = NewStringIf (Ascending = True) ThenMyDataView.Sort = “ID Asc,” + ColName + ” desc”Ascending = FalseMe.TableStyles(0).GridColumnStyles(ColNum).HeaderText = _Me.TableStyles(0).GridColumnStyles(ColNum).HeaderText + ” ↑”SortedColNum = ColNumElseMyDataView.Sort = “ID Asc,” + ColName + ” asc”Ascending = TrueMe.TableStyles(0).GridColumnStyles(ColNum).HeaderText = _Me.TableStyles(0).GridColumnStyles(ColNum).HeaderText + ” ↓”SortedColNum = ColNumEnd IfEnd IfEnd IfEnd Sub’ Disable the footer row of the DataGrid control.Public Sub SetEnableValues(ByVal sender As Object, ByVal e As DataGridDisableCellEventArgs)If (e.Row = RowCount – 1) Thene.EnableValue = FalseElsee.EnableValue = TrueEnd IfEnd SubEnd Class’ Define a custom event arguments class that inherits from the EventArgs class.Public Class DataGridDisableCellEventArgsInherits EventArgsPrivate MyCol As IntegerPrivate MyRow As IntegerPrivate MyEnableValue As BooleanPublic Sub New(ByVal Row As Integer, ByVal Col As Integer)MyRow = RowMyCol = ColMyEnableValue = TrueEnd SubPublic Property Column() As IntegerGetReturn MyColEnd GetSet(ByVal Value As Integer)MyCol = ValueEnd SetEnd PropertyPublic Property Row() As IntegerGetReturn MyRowEnd GetSet(ByVal Value As Integer)MyRow = ValueEnd SetEnd PropertyPublic Property EnableValue() As BooleanGetReturn MyEnableValueEnd GetSet(ByVal Value As Boolean)MyEnableValue = ValueEnd SetEnd PropertyEnd ClassPublic Class MyDataGridTextBoxInherits DataGridTextBoxColumn’ Declare an event for the DataGridDisableCellEventHandler delegate that you have defined.Public Event DataGridDisableCell As DataGridDisableCellEventHandlerPrivate MyCol As Integer’ Save the column number of the column to add the MyDataGridTextBox control to.Public Sub New(ByVal Column As Integer)MyCol = ColumnEnd Sub’ Override the Paint method to set colors for the footer row.Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, _ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, _ByVal rowNum As Integer, ByVal backBrush As System.Drawing.Brush, _ByVal foreBrush As System.Drawing.Brush, ByVal alignToRight As Boolean)’ Initialize the event arguments with the number’ of the current row and the current column.Dim e As New DataGridDisableCellEventArgs(rowNum, MyCol)’ Raise the DataGridDisableCell event.RaiseEvent DataGridDisableCell(Me, e)’ Set the foreground color and the background color for the footer row.If Not e.EnableValue ThenIf DataGridControlVB.FooterColor Is Nothing _Or DataGridControlVB.FooterFontColor Is Nothing ThenbackBrush = Brushes.WhiteforeBrush = Brushes.BlackElsebackBrush = DataGridControlVB.FooterColorforeBrush = DataGridControlVB.FooterFontColorEnd IfEnd If’ Call the Paint event of the DataGridTextBoxColumn class.MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight)End Sub’ Override the Edit method to disable the footer row.Protected Overloads Overrides Sub Edit(ByVal source As System.Windows.Forms.CurrencyManager, _ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal readOnlyFlag As Boolean, _ByVal instantText As String, ByVal cellIsVisible As Boolean)Dim e As DataGridDisableCellEventArgs = Nothing’ Initialize the event arguments with the number’ of the current row and the current column.e = New DataGridDisableCellEventArgs(rowNum, MyCol)’ Raise the DataGridDisableCell event.RaiseEvent DataGridDisableCell(Me, e)’ Call the Edit event of the DataGridTextBoxColumn’ class for all rows other than the footer row.If e.EnableValue ThenMyBase.Edit(source, rowNum, bounds, readOnlyFlag, instantText, cellIsVisible)End IfEnd SubEnd ClassForm1.vbNote In the following code, replace <ServerName> with the appropriate value for an instance of Microsoft SQL Server.

Imports System.DataImports System.Data.SqlClientPublic Class Form1Inherits System.Windows.Forms.FormDim MyConnString As StringDim MyDataSet As DataSet = NothingDim MyDataAdapter As SqlDataAdapter = NothingDim MyConn As SqlConnection#Region ” Windows Form Designer generated code “Public Sub New()MyBase.New()’This call is required by the Windows Form Designer.InitializeComponent()’Add any initialization after the InitializeComponent() callEnd Sub’Form overrides dispose to clean up the component list.Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)If disposing ThenIf Not (components Is Nothing) Thencomponents.Dispose()End IfEnd IfMyBase.Dispose(disposing)End Sub’Required by the Windows Form DesignerPrivate components As System.ComponentModel.IContainer’NOTE: The following procedure is required by the Windows Form Designer’It can be modified using the Windows Form Designer.’Do not modify it using the code editor.Friend WithEvents DataGridControlVB1 As DataGridControl.DataGridControlVB<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()Me.DataGridControlVB1 = New DataGridControl.DataGridControlVBCType(Me.DataGridControlVB1, System.ComponentModel.ISupportInitialize).BeginInit()Me.SuspendLayout()”DataGridControlVB1′Me.DataGridControlVB1.DataMember = “”Me.DataGridControlVB1.DataSourceTable = NothingMe.DataGridControlVB1.HeaderForeColor = System.Drawing.SystemColors.ControlTextMe.DataGridControlVB1.Location = New System.Drawing.Point(0, 0)Me.DataGridControlVB1.Name = “DataGridControlVB1″Me.DataGridControlVB1.Size = New System.Drawing.Size(420, 115)Me.DataGridControlVB1.TabIndex = 0”Form1′Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)Me.ClientSize = New System.Drawing.Size(442, 173)Me.Controls.Add(Me.DataGridControlVB1)Me.Name = “Form1″Me.Text = “Form1″CType(Me.DataGridControlVB1, System.ComponentModel.ISupportInitialize).EndInit()Me.ResumeLayout(False)End Sub#End RegionPrivate Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.LoadDim SqlString As String = “SELECT * FROM discounts”MyConnString = “server=<ServerName>;Integrated Security=SSPI;database=pubs”MyConn = New SqlConnection(MyConnString)MyDataAdapter = New SqlDataAdapter(SqlString, MyConn)MyDataSet = New DataSetTryMyDataAdapter.Fill(MyDataSet, “discounts”)’ Specify the dataset that you want your DataGrid control to use.DataGridControlVB1.GridDataSet = MyDataSet’ Specify the source table that you want your DataGrid control to use.DataGridControlVB1.DataSourceTable = “discounts”‘ Add the columns that you want to sum to an array list in the following format:’ “<ColumnNumber>,summing expression”Dim Summary As New ArrayListSummary.Add(“2,sum(lowqty)”)Summary.Add(“3,sum(highqty)”)’ Map the array list to the SummaryColumns property of your DataGrid control.DataGridControlVB1.SummaryColumns = Summary’ Set the foreground color and the background color for the footer row.DataGridControlVB1.FooterColor = Brushes.BlueVioletDataGridControlVB1.FooterFontColor = Brushes.White’ Bind the DataGrid control to the related data.DataGridControlVB1.BindDataGrid()’ Dispose the data adapter, and then close the connection.Catch DatabaseException As SqlExceptionMessageBox.Show(“Database exception: ” & DatabaseException.Message)Catch OtherException As ExceptionMessageBox.Show(OtherException.Message)FinallyMyDataAdapter.Dispose()MyConn.Dispose()End TryEnd SubEnd Class
Build and then run your applicationOn the Build menu, click Build Solution.On the Debug menu, click Start.
The Form1 form appears. Your custom DataGrid control is present on the Form1 form. The footer row of the DataGrid control contains the sums of the values of the fields that you specified to sum. You cannot edit the footer row. However, when you change the value in any one of the cells, the corresponding footer cell is updated.

How to implement impersonation in an ASP.NET application

Symptoms
This article describes different ways to implement impersonation in an ASP.NET application.
Resolution
If you want to impersonate a user on a thread in ASP.NET, you can use one of the following methods, based on your requirments: Impersonate the IIS authenticated account or userImpersonate a specific user for all the requests of an ASP.NET application Impersonate the authenticating user in codeImpersonate a specific user in codeNote You can use the following code to determine what user the thread is executing as:

System.Security.Principal.WindowsIdentity.GetCurrent().Name
Impersonate the IIS Authenticated Account or User To impersonate the Microsoft Internet Information Services (IIS) authenticating user on every request for every page in an ASP.NET application, you must include an <identity> tag in the Web.config file of this application and set the impersonate attribute to true. For example:

<identity impersonate=”true” />
Impersonate a Specific User for All the Requests of an ASP.NET Application To impersonate a specific user for all the requests on all pages of an ASP.NET application, you can specify the userName and password attributes in the <identity> tag of the Web.config file for that application. For example:

<identity impersonate=”true” userName=”accountname” password=”password” /> Note The identity of the process that impersonates a specific user on a thread must have the “Act as part of the operating system” privilege. By default, the Aspnet_wp.exe process runs under a computer account named ASPNET. However, this account does not have the required privileges to impersonate a specific user. You receive an error message if you try to impersonate a specific user. This information applies only to the .NET Framework 1.0. This privilege is not required for the .NET Framework 1.1.
To work around this problem, use one of the following methods: Grant the “Act as part of the operating system” privilege to the ASPNET account (the least privileged account).
Note Although you can use this method to work around the problem, Microsoft does not recommend this method.Change the account that the Aspnet_wp.exe process runs under to the System account in the <processModel> configuration section of the Machine.config file.
Impersonate the Authenticating User in Code To impersonate the authenticating user (User.Identity) only when you run a particular section of code, you can use the code to follow. This method requires that the authenticating user identity is of type WindowsIdentity.
Visual Basic .NET

Dim impersonationContext As System.Security.Principal.WindowsImpersonationContextDim currentWindowsIdentity As System.Security.Principal.WindowsIdentitycurrentWindowsIdentity = CType(User.Identity, System.Security.Principal.WindowsIdentity)impersonationContext = currentWindowsIdentity.Impersonate()’Insert your code that runs under the security context of the authenticating user here.impersonationContext.Undo() Visual C# .NET

System.Security.Principal.WindowsImpersonationContext impersonationContext;impersonationContext =((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();//Insert your code that runs under the security context of the authenticating user here.impersonationContext.Undo(); Visual J# .NET

System.Security.Principal.WindowsImpersonationContext impersonationContext;impersonationContext =((System.Security.Principal.WindowsIdentity)get_User().get_Identity()).Impersonate();//Insert your code that runs under the security context of the authenticating user here.impersonationContext.Undo();
Impersonate a Specific User in Code To impersonate a specific user only when you run a particular section of code, use the following code:
Visual Basic .NET

<%@ Page Language=”VB” %><%@ Import Namespace = “System.Web” %><%@ Import Namespace = “System.Web.Security” %><%@ Import Namespace = “System.Security.Principal” %><%@ Import Namespace = “System.Runtime.InteropServices” %><script runat=server>Dim LOGON32_LOGON_INTERACTIVE As Integer = 2Dim LOGON32_PROVIDER_DEFAULT As Integer = 0Dim impersonationContext As WindowsImpersonationContextDeclare Function LogonUserA Lib “advapi32.dll” (ByVal lpszUsername As String, _ByVal lpszDomain As String, _ByVal lpszPassword As String, _ByVal dwLogonType As Integer, _ByVal dwLogonProvider As Integer, _ByRef phToken As IntPtr) As IntegerDeclare Auto Function DuplicateToken Lib “advapi32.dll” ( _ByVal ExistingTokenHandle As IntPtr, _ByVal ImpersonationLevel As Integer, _ByRef DuplicateTokenHandle As IntPtr) As IntegerDeclare Auto Function RevertToSelf Lib “advapi32.dll” () As LongDeclare Auto Function CloseHandle Lib “kernel32.dll” (ByVal handle As IntPtr) As LongPublic Sub Page_Load(ByVal s As Object, ByVal e As EventArgs)If impersonateValidUser(“username”, “domain”, “password”) Then’Insert your code that runs under the security context of a specific user here.undoImpersonation()Else’Your impersonation failed. Therefore, include a fail-safe mechanism here.End IfEnd SubPrivate Function impersonateValidUser(ByVal userName As String, _ByVal domain As String, ByVal password As String) As BooleanDim tempWindowsIdentity As WindowsIdentityDim token As IntPtr = IntPtr.ZeroDim tokenDuplicate As IntPtr = IntPtr.ZeroimpersonateValidUser = FalseIf RevertToSelf() ThenIf LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT, token) <> 0 ThenIf DuplicateToken(token, 2, tokenDuplicate) <> 0 ThentempWindowsIdentity = New WindowsIdentity(tokenDuplicate)impersonationContext = tempWindowsIdentity.Impersonate()If Not impersonationContext Is Nothing ThenimpersonateValidUser = TrueEnd IfEnd IfEnd IfEnd IfIf Not tokenDuplicate.Equals(IntPtr.Zero) ThenCloseHandle(tokenDuplicate)End IfIf Not token.Equals(IntPtr.Zero) ThenCloseHandle(token)End IfEnd FunctionPrivate Sub undoImpersonation()impersonationContext.Undo()End Sub</script>Visual C# .NET

<%@ Page Language=”C#”%><%@ Import Namespace = “System.Web” %><%@ Import Namespace = “System.Web.Security” %><%@ Import Namespace = “System.Security.Principal” %><%@ Import Namespace = “System.Runtime.InteropServices” %><script runat=server>public const int LOGON32_LOGON_INTERACTIVE = 2;public const int LOGON32_PROVIDER_DEFAULT = 0;WindowsImpersonationContext impersonationContext; [DllImport("advapi32.dll")]public static extern int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]public static extern bool RevertToSelf();[DllImport("kernel32.dll", CharSet=CharSet.Auto)]public static externbool CloseHandle(IntPtr handle);public void Page_Load(Object s, EventArgs e){ if(impersonateValidUser(“username”, “domain”, “password”)) { //Insert your code that runs under the security context of a specific user here. undoImpersonation(); } else { //Your impersonation failed. Therefore, include a fail-safe mechanism here. }}private bool impersonateValidUser(String userName, String domain, String password){ WindowsIdentity tempWindowsIdentity; IntPtr token = IntPtr.Zero; IntPtr tokenDuplicate = IntPtr.Zero; if(RevertToSelf()) { if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0) { if(DuplicateToken(token, 2, ref tokenDuplicate) != 0) { tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); impersonationContext = tempWindowsIdentity.Impersonate(); if (impersonationContext != null) { CloseHandle(token); CloseHandle(tokenDuplicate); return true; } } } } if(token!= IntPtr.Zero) CloseHandle(token); if(tokenDuplicate!=IntPtr.Zero) CloseHandle(tokenDuplicate); return false;}private void undoImpersonation(){ impersonationContext.Undo();}</script>Visual J# .NET

<%@ Page language=”VJ#” %><%@ Import Namespace=”System.Web” %><%@ Import Namespace=”System.Web.Security” %><%@ Import Namespace=”System.Security.Principal” %><%@ Import Namespace=”System.Runtime.InteropServices” %><script runat=server>public static int LOGON32_LOGON_INTERACTIVE = 2;public static int LOGON32_PROVIDER_DEFAULT = 0;WindowsImpersonationContext impersonationContext; /** @attribute DllImport(“advapi32.dll”) */ public static native int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, System.IntPtr[] phToken);/** @attribute DllImport(“advapi32.dll”, CharSet=CharSet.Auto, SetLastError=true) */ public static native int DuplicateToken(System.IntPtr hToken, int impersonationLevel, System.IntPtr[] hNewToken);/** @attribute DllImport(“kernel32.dll”,CharSet=CharSet.Auto) */ public static nativeboolean CloseHandle(System.IntPtr[] handle);/** @attribute DllImport(“advapi32.dll”, CharSet=CharSet.Auto,SetLastError=true) */ public static native boolean RevertToSelf();public void Page_Load(Object s, System.EventArgs e){ if(impersonateValidUser(“username”, “domain”, ” password”)) { //Insert your code that runs under the security context of a specific user here. undoImpersonation(); } else { //Your impersonation failed. Therefore, include a fail-safe mechanism here. }}private boolean impersonateValidUser(String userName, String domain, String password){ WindowsIdentity tempWindowsIdentity; System.IntPtr[] token = new System.IntPtr[1]; System.IntPtr[] tokenDuplicate = new System.IntPtr[1]; if(RevertToSelf()) { if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, token) != 0) { if(DuplicateToken(token[0], 2, tokenDuplicate) != 0) { tempWindowsIdentity = new WindowsIdentity(tokenDuplicate[0]); impersonationContext = tempWindowsIdentity.Impersonate(); if (impersonationContext != null) { CloseHandle(tokenDuplicate); CloseHandle(token); return true; } } } } if(!token[0].Equals(System.IntPtr.Zero)) CloseHandle(token); if(!tokenDuplicate[0].Equals(System.IntPtr.Zero)) CloseHandle(tokenDuplicate); return false;}private void undoImpersonation(){ impersonationContext.Undo();}</script> Note The identity of the process that impersonates a specific user on a thread must have the “Act as part of the operating system” privilege if the Aspnet_wp.exe process is running on a Microsoft Windows 2000-based computer. The “Act as part of the operating system” privilege is not required if the Aspnet_wp.exe process is running on a Windows XP-based computer or on a Windows Server 2003-based computer. By default, the Aspnet_wp.exe process runs under a computer account named ASPNET. However, this account does not have the required privileges to impersonate a specific user. You receive an error message if you try to impersonate a specific user. .
To work around this problem, use one of the following methods: Grant the “Act as part of the operating system” privilege to the ASPNET account.
Note We do not recommend this method to work around the problem.Change the account that the Aspnet_wp.exe process runs under to the System account in the <processModel> configuration section of the Machine.config file.

How to enable the “Option Strict” and “Option Explicit” statements in Visual Basic applications

Symptoms
This article describes how to enable the Option Strict and Option Explicit statements in Microsoft Visual Basic applications for code-behind files and files that are contained in the App_Code folder.
Resolution
To enable the Option Strict and Option Explicit statements in the code-behind files and files that are contained in the App_Code folder of a Visual Basic application, override the compiler configuration in the system.codedom section of the Web.config file for the application. To do this, add the following code to the Web.config file:

<system.codedom> <compilers> <compiler language=”c#;cs;csharp” extension=”.cs” type=”Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″ warningLevel=”0″/> <compiler language=”vb;vbs;visualbasic;vbscript” extension=”.vb” type=”Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″ warningLevel=”0″ /> </compilers> </system.codedom>

Error message when you use DataReader in Visual Basic .NET: “Invalid attempt to read from column ordinal”

Symptoms
When you use DataReader to read a row, if you try to access columns in that row, you receive an error message similar to the following:

System.InvalidOperationException: Invalid attempt to read from column ordinal ‘0′.With CommandBehavior.SequentialAccess, you may only read from column ordinal ‘2′ or greater.
Resolution
This problem occurs because you executed OleDbCommand or SqlCommand with the System.Data.CommandBehavior.SequentialAccess flag set but did not access the columns sequentially.