dynamically building template columns

J

jonefer

Ok, I found a good article of how to dynamically build template columns
The reason I want to use this is so that I can only set certain columns to
be sortable.


what I'm trying to do is read the value of a column - for example if the
column reads 'General Course' in the first 14 letters... I want that field to
be sortable

So here is the call that actually builds and populates my gridview - I just
wonder why I can't change any properties in the template?

lCount = tb_ActionList.GetActionList(sSL, sDIR, sSup, sLocName,
sDeptName, "Gen").Tables("qActionGrid_GEN").Rows.Count
If lCount = 0 Then
ShowGrid(False)
Me.lblCheck.Text = "No records match the selected criteria"
With Me.lblCheck
.ForeColor = Drawing.Color.Red
End With

Else

'try dynamic adding of template columns
For Each col As DataColumn In ds.Tables("qActionGrid_Gen").Columns
Dim bfield As TemplateField = New TemplateField
bfield.HeaderTemplate = New
GridViewTemplate(ListItemType.Header, col.ColumnName)
bfield.ItemTemplate = New
GridViewTemplate(ListItemType.Item, col.ColumnName)
Dim colchk As String = Left(col.ColumnName, 14)
'If colchk = "General Course" Then
bfield.SortExpression = col.ColumnName
'End If

'bfield.ItemStyle.Font.Names


gvActionList.Columns.Add(bfield)
Next



'=======================================
gvActionList.DataSource = ds
gvActionList.DataBind()


Here is the class

Public Class GridViewTemplate
Implements ITemplate
Private _templateType As ListItemType
Private _columnName As String

Public Sub New(ByVal type As ListItemType, ByVal colname As String)
_templateType = type
_columnName = colname
End Sub

Sub InstantiateIn(ByVal container As System.Web.UI.Control) _
Implements ITemplate.InstantiateIn
Select Case _templateType
Case ListItemType.Header
Dim lbl As Label = New Label
lbl.Text = _columnName
container.Controls.Add(lbl)
' break
Case ListItemType.Item
Dim tb1 As TextBox = New TextBox
AddHandler tb1.DataBinding, AddressOf tb1_DataBinding
tb1.Columns = 4
container.Controls.Add(tb1)
' break
Case ListItemType.EditItem
' break
Case ListItemType.Footer
Dim chkColumn As CheckBox = New CheckBox
chkColumn.ID = "Chk" + _columnName
container.Controls.Add(chkColumn)
' break
End Select
End Sub

Sub tb1_DataBinding(ByVal sender As Object, ByVal e As EventArgs)
Dim txtdata As TextBox = CType(sender, TextBox)
Dim container As GridViewRow = CType(txtdata.NamingContainer,
GridViewRow)
Dim dataValue As Object = DataBinder.Eval(container.DataItem,
_columnName)
If Not (dataValue Is DBNull.Value) Then
txtdata.Text = dataValue.ToString
End If
End Sub
End Class

I feel I am so close to solving this... if I can just get these particular
columns to be searchable it would help me tremendously.
 
C

CaffieneRush

TemplateFields are an overkill if you just want to control sorting
individual columns.
Sorting can be turned off for a particular gridview column by setting
it's SortExpression to an empty string.

Andy
 
J

jonefer

Thank you for answering the post.

Yes. I realize that sorting can be turned off for a particular column by
setting its SortExpression to an empty string BUT how do you do that for
columns that are sometimes there and sometimes not?

I found another article that lets me Format AutoGenerateColumns in an
ASP.NET Grid - The Code Project- ASP.NET

But the author doesn't go as far as tapping into the SortExpression for the
header.


Here is an example of his routine that should be referenced in the
OnRowDataBound event as follows

<asp:GridView id = "MyList" runat = "server"
AutoGenerateColumns-"true"
OnRowDataBound= "GV_RowDataBound"


private void GV_RowDataBound(object o, GridViewRowEventArgs e)
{
// apply custom formatting to data cells
if (e.Row.RowType == DataControlRowType.DataRow)
{
// set formatting for the category cell
TableCell cell = e.Row.Cells[0];
cell.Width = new Unit("120px");
cell.Style["border-right"] = "2px solid #666666";
cell.BackColor = System.Drawing.Color.LightGray;

// set formatting for value cells
for(int i=1; i<e.Row.Cells.Count; i++)
{
cell = e.Row.Cells;

// right-align each of the column cells after the first
// and set the width
cell.HorizontalAlign = HorizontalAlign.Right;
cell.Width = new Unit("90px");

// alternate background colors
if (i % 2 == 1)
cell.BackColor
= System.Drawing.ColorTranslator.FromHtml("#EFEFEF");

// check value columns for a high enough value
// (value >= 8000) and apply special highlighting
if (GetCellValue(cell) >= 8000)
{
cell.Font.Bold = true;
cell.BorderWidth = new Unit("1px");
cell.BorderColor = System.Drawing.Color.Gray;
cell.BorderStyle = BorderStyle.Dotted;
cell.BackColor = System.Drawing.Color.Honeydew;
}

}
}

// apply custom formatting to the header cells
if (e.Row.RowType == DataControlRowType.Header)
{
foreach (TableCell cell in e.Row.Cells)
{
cell.Style["border-bottom"] = "2px solid #666666";
cell.BackColor=System.Drawing.Color.LightGray;
}
}

}


I imagine that what I want to set is in the last part with the Header Cells.
However, I don't know what property to tap into to get to the sort expression.

I've only found luck tapping into it using ItemTemplates.

If you have any ideas, I'm stoked!
 
C

CaffieneRush

It sounds like you want the GridView columns to be autogenerated and
enable sorting only on the column name starts with "General Course"
then make it sortable.

So you've already discovered that autogenerated columns are *not*
added to that gridview's Columns collection otherwise you could have
looped through the Columns collection and check if each column's
HeaderText.StartsWith("General Course") then set that column's
SortExpression accordingly. Therefore sorting on autogenerated
gridviews are either on for all column or off.

However, if you create the columns yourself then you can set the
SortExpression before adding it to the gridview's Columns collection.
Suppose you use boundfields...

For Each col As DataColumn In
ds.Tables("qActionGrid_Gen").Columns
Dim bfield As New BoundField
bfield.HeaderText = col.ColumnName
bfield.DataField = col.ColumnName

If col.ColumnName.StartsWith("General Course") Then
bfield.SortExpression = col.ColumnName
Else
bfield.SortExpression = String.Empty
End If

gvActionList.Columns.Add(bfield)
Next

'=======================================
gvActionList.DataSource = ds
gvActionList.DataBind()

Now to the question of why the author below does not tap into
SortExpression of the autogenerated column in the gridview.
The answer is that he/she could not access the Columns collection
property on the gridview and therefore could not set the
SortExpression on the individual DataControlField within the Columns
collection.

Andy

Thank you for answering the post.

Yes. I realize that sorting can be turned off for a particular column by
setting its SortExpression to an empty string BUT how do you do that for
columns that are sometimes there and sometimes not?

I found another article that lets me Format AutoGenerateColumns in an
ASP.NET Grid - The Code Project- ASP.NET

But the author doesn't go as far as tapping into the SortExpression for the
header.

Here is an example of his routine that should be referenced in the
OnRowDataBound event as follows

<asp:GridView id = "MyList" runat = "server"
AutoGenerateColumns-"true"
OnRowDataBound= "GV_RowDataBound"

private void GV_RowDataBound(object o, GridViewRowEventArgs e)
{
// apply custom formatting to data cells
if (e.Row.RowType == DataControlRowType.DataRow)
{
// set formatting for the category cell
TableCell cell = e.Row.Cells[0];
cell.Width = new Unit("120px");
cell.Style["border-right"] = "2px solid #666666";
cell.BackColor = System.Drawing.Color.LightGray;

// set formatting for value cells
for(int i=1; i<e.Row.Cells.Count; i++)
{
cell = e.Row.Cells;

// right-align each of the column cells after the first
// and set the width
cell.HorizontalAlign = HorizontalAlign.Right;
cell.Width = new Unit("90px");

// alternate background colors
if (i % 2 == 1)
cell.BackColor
= System.Drawing.ColorTranslator.FromHtml("#EFEFEF");

// check value columns for a high enough value
// (value >= 8000) and apply special highlighting
if (GetCellValue(cell) >= 8000)
{
cell.Font.Bold = true;
cell.BorderWidth = new Unit("1px");
cell.BorderColor = System.Drawing.Color.Gray;
cell.BorderStyle = BorderStyle.Dotted;
cell.BackColor = System.Drawing.Color.Honeydew;
}

}
}

// apply custom formatting to the header cells
if (e.Row.RowType == DataControlRowType.Header)
{
foreach (TableCell cell in e.Row.Cells)
{
cell.Style["border-bottom"] = "2px solid #666666";
cell.BackColor=System.Drawing.Color.LightGray;
}
}

}

I imagine that what I want to set is in the last part with the Header Cells.
However, I don't know what property to tap into to get to the sort expression.

I've only found luck tapping into it using ItemTemplates.

If you have any ideas, I'm stoked!

TemplateFields are an overkill if you just want to control sorting
individual columns.
Sorting can be turned off for a particular gridview column by setting
it's SortExpression to an empty string.
 
J

jonefer

before I wrote my last post, I had tried what you suggested.
That loop - for some reason doesn't work cleanly.
It DOES do what you claim, and only adds links to certain columns
HOWEVER, every time the user changes parameters, new blank columns keep
getting added to the gridview, and my gridview gets pushed to the right.

So... I ended up using the author's method below
GV_RowDataBound

and I don't have any problems with the new blank columns.

Is there anyway to access to columns collection within his routine?



It sounds like you want the GridView columns to be autogenerated and
enable sorting only on the column name starts with "General Course"
then make it sortable.

So you've already discovered that autogenerated columns are *not*
added to that gridview's Columns collection otherwise you could have
looped through the Columns collection and check if each column's
HeaderText.StartsWith("General Course") then set that column's
SortExpression accordingly. Therefore sorting on autogenerated
gridviews are either on for all column or off.

However, if you create the columns yourself then you can set the
SortExpression before adding it to the gridview's Columns collection.
Suppose you use boundfields...

For Each col As DataColumn In
ds.Tables("qActionGrid_Gen").Columns
Dim bfield As New BoundField
bfield.HeaderText = col.ColumnName
bfield.DataField = col.ColumnName

If col.ColumnName.StartsWith("General Course") Then
bfield.SortExpression = col.ColumnName
Else
bfield.SortExpression = String.Empty
End If

gvActionList.Columns.Add(bfield)
Next

'=======================================
gvActionList.DataSource = ds
gvActionList.DataBind()

Now to the question of why the author below does not tap into
SortExpression of the autogenerated column in the gridview.
The answer is that he/she could not access the Columns collection
property on the gridview and therefore could not set the
SortExpression on the individual DataControlField within the Columns
collection.

Andy

Thank you for answering the post.

Yes. I realize that sorting can be turned off for a particular column by
setting its SortExpression to an empty string BUT how do you do that for
columns that are sometimes there and sometimes not?

I found another article that lets me Format AutoGenerateColumns in an
ASP.NET Grid - The Code Project- ASP.NET

But the author doesn't go as far as tapping into the SortExpression for the
header.

Here is an example of his routine that should be referenced in the
OnRowDataBound event as follows

<asp:GridView id = "MyList" runat = "server"
AutoGenerateColumns-"true"
OnRowDataBound= "GV_RowDataBound"

private void GV_RowDataBound(object o, GridViewRowEventArgs e)
{
// apply custom formatting to data cells
if (e.Row.RowType == DataControlRowType.DataRow)
{
// set formatting for the category cell
TableCell cell = e.Row.Cells[0];
cell.Width = new Unit("120px");
cell.Style["border-right"] = "2px solid #666666";
cell.BackColor = System.Drawing.Color.LightGray;

// set formatting for value cells
for(int i=1; i<e.Row.Cells.Count; i++)
{
cell = e.Row.Cells;

// right-align each of the column cells after the first
// and set the width
cell.HorizontalAlign = HorizontalAlign.Right;
cell.Width = new Unit("90px");

// alternate background colors
if (i % 2 == 1)
cell.BackColor
= System.Drawing.ColorTranslator.FromHtml("#EFEFEF");

// check value columns for a high enough value
// (value >= 8000) and apply special highlighting
if (GetCellValue(cell) >= 8000)
{
cell.Font.Bold = true;
cell.BorderWidth = new Unit("1px");
cell.BorderColor = System.Drawing.Color.Gray;
cell.BorderStyle = BorderStyle.Dotted;
cell.BackColor = System.Drawing.Color.Honeydew;
}

}
}

// apply custom formatting to the header cells
if (e.Row.RowType == DataControlRowType.Header)
{
foreach (TableCell cell in e.Row.Cells)
{
cell.Style["border-bottom"] = "2px solid #666666";
cell.BackColor=System.Drawing.Color.LightGray;
}
}

}

I imagine that what I want to set is in the last part with the Header Cells.
However, I don't know what property to tap into to get to the sort expression.

I've only found luck tapping into it using ItemTemplates.

If you have any ideas, I'm stoked!

TemplateFields are an overkill if you just want to control sorting
individual columns.
Sorting can be turned off for a particular gridview column by setting
it's SortExpression to an empty string.

Ok, I found a good article of how to dynamically build template columns
The reason I want to use this is so that I can only set certain columns to
be sortable.
what I'm trying to do is read the value of a column - for example if the
column reads 'General Course' in the first 14 letters... I want that field to
be sortable
So here is the call that actually builds and populates my gridview - I just
wonder why I can't change any properties in the template?
lCount = tb_ActionList.GetActionList(sSL, sDIR, sSup, sLocName,
sDeptName, "Gen").Tables("qActionGrid_GEN").Rows.Count
If lCount = 0 Then
ShowGrid(False)
Me.lblCheck.Text = "No records match the selected criteria"
With Me.lblCheck
.ForeColor = Drawing.Color.Red
End With

'try dynamic adding of template columns
For Each col As DataColumn In ds.Tables("qActionGrid_Gen").Columns
Dim bfield As TemplateField = New TemplateField
bfield.HeaderTemplate = New
GridViewTemplate(ListItemType.Header, col.ColumnName)
bfield.ItemTemplate = New
GridViewTemplate(ListItemType.Item, col.ColumnName)
Dim colchk As String = Left(col.ColumnName, 14)
'If colchk = "General Course" Then
bfield.SortExpression = col.ColumnName
'End If


'=======================================
gvActionList.DataSource = ds
gvActionList.DataBind()
Here is the class
Public Class GridViewTemplate
Implements ITemplate
Private _templateType As ListItemType
Private _columnName As String
Public Sub New(ByVal type As ListItemType, ByVal colname As String)
_templateType = type
_columnName = colname
End Sub
Sub InstantiateIn(ByVal container As System.Web.UI.Control) _
Implements ITemplate.InstantiateIn
Select Case _templateType
Case ListItemType.Header
Dim lbl As Label = New Label
lbl.Text = _columnName
container.Controls.Add(lbl)
' break
Case ListItemType.Item
Dim tb1 As TextBox = New TextBox
AddHandler tb1.DataBinding, AddressOf tb1_DataBinding
tb1.Columns = 4
container.Controls.Add(tb1)
' break
Case ListItemType.EditItem
' break
Case ListItemType.Footer
Dim chkColumn As CheckBox = New CheckBox
chkColumn.ID = "Chk" + _columnName
container.Controls.Add(chkColumn)
' break
End Select
End Sub
Sub tb1_DataBinding(ByVal sender As Object, ByVal e As EventArgs)
Dim txtdata As TextBox = CType(sender, TextBox)
Dim container As GridViewRow = CType(txtdata.NamingContainer,
GridViewRow)
Dim dataValue As Object = DataBinder.Eval(container.DataItem,
_columnName)
If Not (dataValue Is DBNull.Value) Then
txtdata.Text = dataValue.ToString
End If
End Sub
End Class
I feel I am so close to solving this... if I can just get these particular
columns to be searchable it would help me tremendously.

 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top