Introduction
I was asked by someone how to create a DataGrid
column style as a LinkLabel
for a DataGrid
. I present below the code for a control for a DataGrid
column style made by me. I have made some changes in the code and I am updating this article by submitting the code for the article. Many people asked for the code of this article.
There are many ColumnStyle
s defined such as DataGridComboColumn
, DataGridLabelColumn
etc.
Using the Code
Overriding the methods
To create a column style, you need to subclass the abstract DataGridColumnStyle
class. Here is the list of the methods that you need to implement:
Protected Overrides Sub Abort(ByVal rowNum As Integer)
The function Abort(ByVal rowNum as Integer)
determines how the active column cell is to react to the user's request to interrupt the editing procedure.
Protected Overrides Function Commit (ByVal datasource As _
CurrencyManager, ByVal rowNum As Integer) As Boolean
The function Commit()
implements a logic that updates the cell with the new value, and prepares the updated data to be pushed back to the property descriptor using the base class SetColumnValueAtRow
method.
Protected Overloads Overrides Sub Edit(ByVal source As _
System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal bounds _
As System.Drawing.Rectangle, ByVal [readOnly] As Boolean, _
ByVal instantText As String)
Edit
allows you to prepare the cell for editing, using the specified System.Windows.Forms.CurrencyManager
, row number, and System.Drawing.Rectangle
parameters.
Protected Overrides Function GetMinimumHeight() As Integer
GetMinimumHeight()
returns the desired minimum height of the cells in the grid.
Protected Overrides Function GetPreferredHeight(ByVal g _
As Graphics, ByVal value As Object) As Integer
GetPreferredHeight()
returns the preferred cell height. When the user double-clicks on a row border, this method is invoked on all of the column styles that reside in the current table style's GridColumnStyleCollection
.
Protected Overrides Function GetPreferredSize(ByVal g _
As Graphics, ByVal value As Object) As System.Drawing.Size
GetPreferredSize()
returns the preferred cell size. This method does the same thing as the GetPreferredHeight
method, only it is invoked when the user double-clicks on a column border. The column to the left of the border is then set to the width of the returned Size
object.
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)
In this Paint()
method, call the following Paint()
method, passing alignToRight
value as False
.
Protected Overloads Overrides Sub Paint (ByVal g As Graphics, _
ByVal bounds As Rectangle, ByVal source As CurrencyManager, _
ByVal rowNum As Integer, ByVal backBrush As Brush, _
ByVal foreBrush As Brush, ByVal alignToRight As Boolean)
This is the second of the three overloaded (and second of the two abstract) Paint
methods in DataGridColumnStyle
. This method paints the cells in the column, one cell at a time. You also receive a reference to a CurrencyManager
object that represents the binding and contains the data that is to be displayed in the grid. By invoking the DataGridColumnStyle
's GetColumnValueAtRow
method, you can obtain the value for the current cell.
Creating Custom ColumnStyles
Protected Overloads Overrides Sub Paint(ByVal g As Graphics, _
ByVal bounds As Rectangle, ByVal source As CurrencyManager, _
ByVal rowNum As Integer, ByVal backBrush As Brush, _
ByVal foreBrush As Brush, ByVal alignToRight As Boolean)
Dim o As Object = Me.GetColumnValueAtRow([source], rowNum)
Dim linkText As String = Microsoft.VisualBasic.IIf((o Is Nothing _
OrElse o Is DBNull.Value), Me.NullText, o.ToString)
If (links.Contains(rowNum)) Then
m_link = CType(links(rowNum), LinkLabel)
If Not (m_link.Bounds.Equals(bounds)) Then
m_link.Bounds = bounds
m_link.Visible = True
End If
Else
m_link = New LinkLabel
m_link.Text = linkText
m_link.Parent = Me.DataGridTableStyle.DataGrid
m_link.Links.Add(0, linkText.Length, o)
m_link.Bounds = bounds
AddHandler m_link.LinkClicked, AddressOf link_LinkClicked
links(rowNum) = m_link
End If
End Sub
Usage: Bind Controls to DataGrid - How to use the column style in your application?
Private Sub BindControls()
Dim dmTable As New DataTable("Test")
dmTable.Columns.Add(New DataColumn("SNO", GetType(Integer)))
dmTable.Columns.Add(New DataColumn("AuthorName", GetType(String)))
dmTable.Columns.Add(New DataColumn("WebAddress", GetType(String)))
Dim dr As DataRow = dmTable.NewRow()
dr("SNO") = 1
dr("AuthorName") = "Chris"
dr("WebAddress") = "http://msdn.microsoft.com/smartclient/" & _
"default.aspx?pull=/library/en-us/" & _
"dnwinforms/html/datagridcolumnstyle2.asp"
dmTable.Rows.Add(dr)
Dim dr2 As DataRow = dmTable.NewRow()
dr2("SNO") = 2
dr2("AuthorName") = "Evan"
dr2("WebAddress") = "http://msdn.microsoft.com/smartclient/default.aspx" & _
"?pull=/library/en-us/dnwinforms/html/" & _
"datagridcolumnstyle1.asp"
dmTable.Rows.Add(dr2)
Dim dr3 As DataRow = dmTable.NewRow()
dr3("SNO") = 3
dr3("AuthorName") = "Chris"
dr3("WebAddress") = "http://www.micrsoft.com/"
dmTable.Rows.Add(dr3)
dataGrid.TableStyles.Add(CreateTableStyle())
dataGrid.DataSource = dmTable
End Sub
Create Table Style:
Private Function CreateTableStyle() As DataGridTableStyle
Dim dst As New DataGridTableStyle
dst.MappingName = "Test"
Dim cs As New ColumnStyles.ColumnStyles.DataGridLinkLabelColumn
AddHandler cs.LinkClicked, AddressOf cs_LinkClicked
cs.MappingName = "WebAddress"
cs.HeaderText = "Web Address"
Dim cb As New DataGridTextBoxColumn
cb.MappingName = "SNO"
cb.HeaderText = "S No"
Dim cs2 As New DataGridTextBoxColumn
cs2.MappingName = "AuthorName"
cs2.HeaderText = "Author Name"
dst.GridColumnStyles.Add(cb)
dst.GridColumnStyles.Add(cs2)
dst.GridColumnStyles.Add(cs)
Return dst
End Function
Adding handler for the LinkClicked
event:
Private Sub cs_LinkClicked(ByVal sender As Object, _
ByVal e As LinkLabelLinkClickedEventArgs)
MessageBox.Show("cs_linkclicked:You have clicked the link")
End Sub
To Fix It
If the contents of the column are larger (as seen in the figure), then it cannot be viewed properly even if we increase the size of the DataGrid
column.
Acknowledgements
Many thanks for giving the idea of how to create a DataGrid
column style: Styling with the DataGridColumnStyle, Part 1 by Chris Sano. There is also another article by Chris Sano describing DataGrid
column styles for further reading. Many thanks to all of those who have appreciated and are using the DLL in their projects.