Hi BugHunter,
Since your no of columns varies based on ViewState you need to dynamically add columns to GridView.
For more details refer below article.
Database
For this example I have used of Northwind database that you can download using the link given below.
Download Northwind Database
HTML
<asp:GridView ID="gvDocType" AutoGenerateColumns="false" EmptyDataText="No Mapping Column Selected"
CssClass="table table-hover" runat="server" OnRowDataBound="OnRowDataBound">
</asp:GridView>
Namespaces
C#
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
VB.Net
Imports System.Configuration
Imports System.Data
Imports System.Data.SqlClient
Code
C#
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindS_Grid();
}
}
private void BindS_Grid()
{
ViewState["VS_SelectedColoumnVal"] = "ContactName,Country";
string Query = @"SELECT TOP 5 " + ViewState["VS_SelectedColoumnVal"] + " FROM Customers";
DataTable dt = GetData(Query);
for (int i = 0; i < dt.Columns.Count; i++)
{
BoundField bfield = new BoundField();
bfield.HeaderText = dt.Columns[i].ColumnName;
bfield.DataField = dt.Columns[i].ColumnName;
gvDocType.Columns.Add(bfield);
}
TemplateField tfield = new TemplateField();
tfield.HeaderText = "Type";
gvDocType.Columns.Add(tfield);
gvDocType.DataSource = dt;
gvDocType.DataBind();
}
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataTable dt = new DataTable();
dt.Columns.Add("Text");
dt.Columns.Add("Value");
dt.Rows.Add("A", "A");
dt.Rows.Add("B", "B");
dt.Rows.Add("C", "C");
dt.Rows.Add("D", "D");
dt.Rows.Add("E", "E");
dt.Rows.Add("F", "F");
dt.Rows.Add("F", "F");
dt.Rows.Add("G", "G");
dt.Rows.Add("H", "H");
dt.Rows.Add("I", "I");
DropDownList ddl_Type = new DropDownList();
ddl_Type.CssClass = "form-control";
ddl_Type.DataSource = dt;
ddl_Type.DataTextField = "Text";
ddl_Type.DataValueField = "Value";
ddl_Type.DataBind();
ddl_Type.Items.Insert(0, new ListItem { Text = "--Select--", Value = "--Select--" });
e.Row.Cells[gvDocType.Columns.Count - 1].Controls.Add(ddl_Type);
}
}
private DataTable GetData(string query)
{
string conString = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
SqlCommand cmd = new SqlCommand(query);
using (SqlConnection con = new SqlConnection(conString))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
return dt;
}
}
}
}
VB.Net
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
If Not IsPostBack Then
BindS_Grid()
End If
End Sub
Private Sub BindS_Grid()
ViewState("VS_SelectedColoumnVal") = "ContactName,Country"
Dim Query As String = "SELECT TOP 5 " & ViewState("VS_SelectedColoumnVal") & " FROM Customers"
Dim dt As DataTable = GetData(Query)
For i As Integer = 0 To dt.Columns.Count - 1
Dim bfield As BoundField = New BoundField()
bfield.HeaderText = dt.Columns(i).ColumnName
bfield.DataField = dt.Columns(i).ColumnName
gvDocType.Columns.Add(bfield)
Next
Dim tfield As TemplateField = New TemplateField()
tfield.HeaderText = "Type"
gvDocType.Columns.Add(tfield)
gvDocType.DataSource = dt
gvDocType.DataBind()
End Sub
Protected Sub OnRowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim dt As DataTable = New DataTable()
dt.Columns.Add("Text")
dt.Columns.Add("Value")
dt.Rows.Add("A", "A")
dt.Rows.Add("B", "B")
dt.Rows.Add("C", "C")
dt.Rows.Add("D", "D")
dt.Rows.Add("E", "E")
dt.Rows.Add("F", "F")
dt.Rows.Add("F", "F")
dt.Rows.Add("G", "G")
dt.Rows.Add("H", "H")
dt.Rows.Add("I", "I")
Dim ddl_Type As DropDownList = New DropDownList()
ddl_Type.CssClass = "form-control"
ddl_Type.DataSource = dt
ddl_Type.DataTextField = "Text"
ddl_Type.DataValueField = "Value"
ddl_Type.DataBind()
ddl_Type.Items.Insert(0, New ListItem With {.Text = "--Select--", .Value = "--Select--"})
e.Row.Cells(gvDocType.Columns.Count - 1).Controls.Add(ddl_Type)
End If
End Sub
Private Function GetData(ByVal query As String) As DataTable
Dim conString As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
Dim cmd As SqlCommand = New SqlCommand(query)
Using con As SqlConnection = New SqlConnection(conString)
Using sda As SqlDataAdapter = New SqlDataAdapter()
cmd.Connection = con
sda.SelectCommand = cmd
Using dt As DataTable = New DataTable()
sda.Fill(dt)
Return dt
End Using
End Using
End Using
End Function
Screenshot