Click here to Skip to main content
15,885,216 members
Articles / Desktop Programming / Windows Forms
Article

LinkLabel DataGrid Column

Rate me:
Please Sign up or sign in to vote.
4.38/5 (12 votes)
20 Oct 2005CDDL2 min read 100.3K   637   34   16
A simple DataGrid column for LinkLabels.

Introduction

I needed to include a DataGrid column with a click-able cell. I found no valid solutions on the net (except some sold control packages and some tricks like mousedown and mousemove/hit-test on the grid) and I saw that many were asking for it... I decided to write it on my own. It's very simple and basic but it works very well.

This is what I needed and this is what I wrote, you may want to adapt it to your needs.

Missing you-may-need-them things (add them yourself)

  • Font change on the grid.
  • Right to left implementation.
  • Visited links.
  • Underline with no mouse on it (I needed the underline to appear when the mouse moves over the link text).
  • Custom colorization for the link.

How it looks

Normal gridCursor in cellCursor on linkCursor on link
(row selected)

How it works

The control overrides some DataGridColumnStyle methods (as you have to do when you write a custom ColumnStyle). When the control is initialized (in its constructor) a generic LinkLabel (this will be the main component that reacts to the clicks) is initialized with its standard size. When the TableStyle is bound to a DataGrid the control binds to some events.

  • MouseMove - Used to show/hide the control when the user moves the cursor on the grid.
  • DataSourceChanged - Used to hide the control (if visible) when the Datagrid.Datasource changes.
  • BindingContextChanged - Used to hide the control (if visible) when the grid binding to data source changes.
  • PositionChanged (DataBinding) - Used to hide the control (if visible) when the position of the binding in the datasource changes. (IE: you click the link and the DataGrid.Datasource is loaded with different data).

Overridden methods

  • Editing: Abort, Commit, Edit
  • Painting: Paint (with overloads)
  • Cell size: GetMinimumHeight, GetPreferredHeight, GetPreferredSize
  • Handling: SetDataGridInColumn, ConcedeFocus

How to use it

(Code used to take the pictures above)

VB
Private Sub SetGridStyle()
    Dim grdStyle As New DataGridTableStyle

    'Other columns...

    Dim grdStileColEqv As New DataGridColumns.LinkLabel
    grdStileColEqv.MappingName = "Equivalenti"
    grdStileColEqv.HeaderText = "Eqv."
    grdStileColEqv.Alignment = HorizontalAlignment.Center
    grdStileColEqv.NullText = ""
    grdStileColEqv.Width = 40
    AddHandler grdStileColEqv.LinkClicked, AddressOf LinkClicked
    grdStyle.GridColumnStyles.Add(grdStileColEqv)

    grdLista.TableStyles.Add(grdListaStyle)
End Sub

Private Sub LinkClicked(ByVal sender As Object, _
            ByVal e As LinkLabelLinkClickedEventArgs)
    'Click handler code goes here.
    'if you need to access data of the row clicked
    '(for example to open a browser with the clicked url)
    'DirectCast(e.Link.LinkData, DataRowView)
    'contains the whole clicked row.
End Sub

Comments

I hope you'll find this code useful. If you want to contribute fixing bugs and/or adding functions, let me know. I'll modify the code accordingly.

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)


Written By
Software Developer (Senior)
Italy Italy
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalproblem Pin
jose angelo santos14-Jan-09 1:15
jose angelo santos14-Jan-09 1:15 
Generalthanks Pin
brigno12-Jan-07 8:47
brigno12-Jan-07 8:47 
Questionhelp Pls Pin
lionvnit29-Oct-06 22:34
lionvnit29-Oct-06 22:34 
AnswerRe: help Pls Pin
Lino Barreca29-Oct-06 23:40
Lino Barreca29-Oct-06 23:40 
GeneralRe: help Pls Pin
lionvnit30-Oct-06 0:12
lionvnit30-Oct-06 0:12 
QuestionUnnecessarily Complicated? Pin
Jay M Miller12-Apr-06 16:16
Jay M Miller12-Apr-06 16:16 
I was happy to find this, but ran into a serious block when I realized that it doesn't work for multiple columns in the same table. The MouseMove event handler is bound to the table, not to an individual column. After a bit more searching I now have the following simpler code that mostly accomplishes the same thing (I haven't implemented every option yet) by creating a LinkLabel for every cell, rather than having a single control that is hidden when leaving a cell.

This is based on another Code Project article by Nidhi Shrivastava (http://www.codeproject.com/vb/net/Datagrid_ColumnStyles.asp), with a bit of your code thrown in:

using System;
using System.Windows.Forms;
using System.Data;
using System.Collections;

namespace CustomControls
{
/// <summary>
/// Summary description for LinkLabelColumnStyle.
/// </summary>
public class DataGridLinkLabelColumn : DataGridColumnStyle
{
private ArrayList _linkList = new ArrayList();

public event LinkLabelLinkClickedEventHandler LinkClicked;

public DataGridLinkLabelColumn()
{
}

protected override void Abort(int rowNum)
{
// Do nothing...this is not an editable column style
}

protected override bool Commit(CurrencyManager dataSource, int rowNum)
{
// Do nothing...this is not an editable column style
return false;
}

protected override void Edit(CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
{
// Do nothing...this is not an editable column style
}

protected override int GetMinimumHeight()
{
return 0;
}

protected override int GetPreferredHeight(System.Drawing.Graphics g, object value)
{
return GetPreferredSize(g, value).Height;
}

protected override System.Drawing.Size GetPreferredSize(System.Drawing.Graphics g, object value)
{
LinkLabel temp = new LinkLabel();
temp.Text = (value == null ? string.Empty : value.ToString());

return new System.Drawing.Size(temp.PreferredWidth, temp.PreferredHeight);
}

protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, CurrencyManager source, int rowNum)
{
Paint(g, bounds, source, rowNum, false);
}

protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight)
{
Paint(g, bounds, source, rowNum, null, null, alignToRight);
}

protected void AllocateControls(int count)
{
_linkList.Clear();

for (int i = 0; i < count; ++i)
{
LinkLabel l = new LinkLabel();
l.LinkBehavior = LinkBehavior.HoverUnderline;
l.Visible = false;
l.Links.Add(0, 0, null);
l.Parent = DataGridTableStyle.DataGrid;
l.LinkClicked += new LinkLabelLinkClickedEventHandler(LinkLabelClicked);
_linkList.Add(l);
}
}

private LinkLabel GetLinkLabel(int rowNum)
{
return (LinkLabel) _linkList[rowNum];
}

protected override void Paint(
System.Drawing.Graphics g,
System.Drawing.Rectangle bounds,
CurrencyManager source,
int rowNum,
System.Drawing.Brush backBrush,
System.Drawing.Brush foreBrush,
bool alignToRight)
{
// Here's the real work. Create a linklabel for every row

// First, if the list doesn't have enough values, grow the list
if (_linkList.Count <= source.List.Count)
{
AllocateControls(source.List.Count);
}

// Now retrieve the specific control for this cell
LinkLabel rowLink = (LinkLabel) _linkList[rowNum];

object cellValue = GetColumnValueAtRow(source, rowNum);
string linkText = cellValue == null ? string.Empty : cellValue.ToString();
rowLink.Text = linkText;
LinkLabel.Link link = rowLink.Links[0];
link.LinkData = source.List[rowNum];
link.Length = linkText.Length;
rowLink.Bounds = bounds;
rowLink.Visible = true;
}

private void LinkLabelClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
if (LinkClicked != null)
{
LinkClicked(sender, e);
}
}
}
}

AnswerRe: Unnecessarily Complicated? Pin
Lino Barreca12-Apr-06 21:40
Lino Barreca12-Apr-06 21:40 
AnswerRe: Unnecessarily Complicated? Pin
imadulhaq25-May-06 7:53
imadulhaq25-May-06 7:53 
GeneralRe: Unnecessarily Complicated? Pin
imadulhaq25-May-06 7:54
imadulhaq25-May-06 7:54 
QuestionHow to incorporate your file into a project Pin
soloflexx19-Jan-06 8:10
soloflexx19-Jan-06 8:10 
GeneralClick Event Handler Pin
junoface13-Dec-05 4:45
junoface13-Dec-05 4:45 
GeneralRe: Click Event Handler Pin
Lino Barreca13-Dec-05 22:01
Lino Barreca13-Dec-05 22:01 
GeneralRe: Click Event Handler Pin
junoface14-Dec-05 1:17
junoface14-Dec-05 1:17 
GeneralVery very nice, but some problems Pin
Desma30-Nov-05 21:52
Desma30-Nov-05 21:52 
GeneralRe: Very very nice, but some problems Pin
Lino Barreca30-Nov-05 22:18
Lino Barreca30-Nov-05 22:18 
GeneralVery useful!! Pin
PazzoDiTe21-Oct-05 12:41
PazzoDiTe21-Oct-05 12:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.