Handling link clicks in a DataGridViewLinkColumn

L

lilfos

I feel like I'm missing something basic here, but I can't find anything
that answers my questions in MSDN or Google Groups. I have two link
columns in my DataGridView. I managed to bind them to columns in a
DataTable using the DataPropertyName property. All other columns are
bound manually. The cells look good, but they don't function properly
(well, at all). I can't get my click handler to figure out what link
was clicked.

The GUI design calls for one column to contain mailto links and one to
contain web page links. The mailtos should do the equivalent of
wrapping the email address displayed in the cell with the appropriate
<a> tag structure. Clicking it would launch a new message window from
the default email editor. The other column should show a page title in
each cell and handle the click by popping up a browser and loading the
desired URL.

Question 1: How do I handle the click for the link itself...not the
row, not the whole grid...just the link?? Everything I read says
something like, bind the column manually and use the cellclick event.
Does this mean that I need to loop through every row in table, add a
cell to the link column, and add an event handler for that cell that
builds an <a> tag and performs the desired action? That would be
really inelegant.

Question 2: When using a DataGridViewLinkColumn, what are the
equivalent of the Text and NavigateURL properties? Do I have to build
a link control for each cell and then set that into the Value property
of the DataGridViewLinkCell?

Bonus Question: This DataGridView supports dragging (drag from, but not
drop to). The MouseDown event seems to prevent the CellClick event
from firing. Assuming I can work everything else out, can I bubble up
the click so that MouseDown will handle a MouseDown/hold whereas a full
click would fire the click event?

Like I said, I feel like I'm just not getting the
DataGridViewLinkColumn. Other than alter text appearance, it really
doesn't seem to do anything useful. What am I missing??

Thanks
 
Q

Quick

Wow how funny is this, I'm right in the middle of the same problem...
and I have the same feeling I'm missing something very basic here...
any help here would be greatly appreciated.

-Quick
 
L

lilfos

In the first paragraph, I meant to say that all other columns are
generated automatically by binding to a DataTable.

Also, I'm using C#.
 
B

Bart Mermuys

Hi,

lilfos said:
I feel like I'm missing something basic here, but I can't find anything
that answers my questions in MSDN or Google Groups. I have two link
columns in my DataGridView. I managed to bind them to columns in a
DataTable using the DataPropertyName property. All other columns are
bound manually. The cells look good, but they don't function properly
(well, at all). I can't get my click handler to figure out what link
was clicked.

The GUI design calls for one column to contain mailto links and one to
contain web page links. The mailtos should do the equivalent of
wrapping the email address displayed in the cell with the appropriate
<a> tag structure. Clicking it would launch a new message window from
the default email editor. The other column should show a page title in
each cell and handle the click by popping up a browser and loading the
desired URL.

Question 1: How do I handle the click for the link itself...not the
row, not the whole grid...just the link?? Everything I read says
something like, bind the column manually and use the cellclick event.

Yes, handle the DataGridView.CellContentClick and check if the column is one
of your link columns, eg. :

private void employeeDataGridView_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 2) // 3th column is a linkcolumn
{
// access cell value, you could also access other cell values
Console.WriteLine( yourDataGridView[e.ColumnIndex, e.RowIndex].Value );

// or if you want access to the bound object
// yourDataGridView.Rows[e.RowIndex].DataBoundItem

// do something
}
}

To start the default browser or mail program you could use Process.Start
(System.Diagnostics), eg. :
Process.Start( "http://www.google.com" );
Process.Start( "mailto:someon@..." );

There is no such a thing as <a> tag in winforms.

HTH,
Greetings
 
R

Roman Wagner

Yes, handle the DataGridView.CellContentClick and check if the column is one
of your link columns, eg. :

private void employeeDataGridView_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 2) // 3th column is a linkcolumn
{
// access cell value, you could also access other cell values
Console.WriteLine( yourDataGridView[e.ColumnIndex, e.RowIndex].Value );

// or if you want access to the bound object
// yourDataGridView.Rows[e.RowIndex].DataBoundItem

// do something
}
}

well this works but if the schema of your datagrid changes you have to
change your code.
Try the following:
if you handle the cellmouseclick event you have to check the indexes of
the eventargs, means:

//ignore header or somewhere else clicks
if(e.RowIndex < 0 || e.RowIndex >= myGrid.Rows.Count || e.ColumnIndex <
0 || e.ColumnIndex >= myGrid.Columns.Count) return;

//do not use fixed indexes
DataGridViewLinkCell linkCell =
myGrid.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewLinkCell;

if(linkCell != null)
{
//do something
}
 
B

Bart Mermuys

Hi,

Roman Wagner said:
Yes, handle the DataGridView.CellContentClick and check if the column is
one
of your link columns, eg. :

private void employeeDataGridView_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 2) // 3th column is a linkcolumn
{
// access cell value, you could also access other cell values
Console.WriteLine( yourDataGridView[e.ColumnIndex,
e.RowIndex].Value );

// or if you want access to the bound object
// yourDataGridView.Rows[e.RowIndex].DataBoundItem

// do something
}
}

well this works but if the schema of your datagrid changes you have to
change your code.
Try the following:
if you handle the cellmouseclick event you have to check the indexes of
the eventargs, means:

//ignore header or somewhere else clicks
if(e.RowIndex < 0 || e.RowIndex >= myGrid.Rows.Count || e.ColumnIndex <
0 || e.ColumnIndex >= myGrid.Columns.Count) return;

//do not use fixed indexes
DataGridViewLinkCell linkCell =
myGrid.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewLinkCell;

if(linkCell != null)
{
//do something
}

Sure that would be better, but it would only work if the OP doesn't want
distinct behaviour for the _two_ DGVLinkColumn he mentioned.

Greetings
 
R

Roman Wagner

Sure that would be better, but it would only work if the OP doesn't want
distinct behaviour for the _two_ DGVLinkColumn he mentioned.

Thats why we have the Tag property.
 

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

Top