LinkLabel in a datagrid on a Windows form

G

Guest

I need to put linklabels in a datagrid on a Windows form when the form
first loads.

For example:

Microsoft website www.microsoft.com
Google website www.google.com

I would like all the rows in the second column to be displayed as a
linklabel not only when it goes into edit mode.

I have looked at the combobox examples but am unable to extrapolate. I have
working code that puts the text in a linklabel when it goes into the edit
mode but that isn't what I need.

If possible, I would like VB code. I have posted this on the VB newsgroup
but received no replies. If you could provide a code example, I would be most
appreciative.

Thanks!

Suz
--
 
G

Guest

..NET Framework 2.0 Supports LinkLabels in the DataGrid. Another solution
would be to OwnerDraw a ListView in Details mode and HitTest the cell that
the link resides in to cause fire whatever event you are using to navigate to
those links.
 
G

Guest

Hi!

Thanks for your reply. I know that it is supported in the datagrid, I just
don't know how to do it.

Due to the scope of the project, a listview won't work.

Suz
 
J

Jeffrey Tan[MSFT]

Hi Suz,

Thanks for your posting!!

Yes, just as Daisuke said, in .Net Framework, in a new control
DataGridView, there will be a build-in DataGridViewLinkColumn gives what
you need. But current now, the only supported build-in Columns are TextBox
and checkboxes.

If you want to implement a DataGridLinkLabelColumn yourself, seen from your
original post, I think your obstacle is: in non-edit mode, how is the
linkLabel displayed? I will clarify this for you:

Actually, for a DataGridColumnStyle, there is only one control in that
column, and in non-edit mode, the control will be invisible state. And it
will go into the edit mode cell when Edit protected method is invoked.(I
think you may have seen this in combobox sample). So for DataGridBoolColumn
etc, for DataGridCell that is not in edit mode, it is not actually a "TRUE"
checkbox control, DataGridBoolColumn just draws a dummy checkbox in every
non-edit mode cell. If we use Reflector to view DataGridBoolColumn.Paint
method, we will see:
protected internal override void Paint(Graphics g, Rectangle bounds,
CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush, bool
alignToRight)
{
object obj1 = (this.isEditing && (this.editingRow == rowNum)) ?
this.currentValue : this.GetColumnValueAtRow(source, rowNum);
ButtonState state1 = ButtonState.Inactive;
if (!Convert.IsDBNull(obj1))
{
state1 = ((bool) obj1) ? ButtonState.Checked :
ButtonState.Normal;
}
Rectangle rectangle1 = this.GetCheckBoxBounds(bounds, alignToRight);
Region region1 = g.Clip;
g.ExcludeClip(rectangle1);
Brush brush1 = this.DataGridTableStyle.IsDefault ?
this.DataGridTableStyle.DataGrid.SelectionBackBrush :
this.DataGridTableStyle.SelectionBackBrush;
if ((this.isSelected && (this.editingRow == rowNum)) &&
!this.IsReadOnly())
{
g.FillRectangle(brush1, bounds);
}
else
{
g.FillRectangle(backBrush, bounds);
}
g.Clip = region1;
if (state1 == ButtonState.Inactive)
{
ControlPaint.DrawMixedCheckBox(g, rectangle1,
ButtonState.Checked);
}
else
{
ControlPaint.DrawCheckBox(g, rectangle1, state1);
}
if ((this.IsReadOnly() && this.isSelected) && (source.Position ==
rowNum))
{
bounds.Inflate(-1, -1);
Pen pen1 = new Pen(brush1);
pen1.DashStyle = DashStyle.Dash;
g.DrawRectangle(pen1, bounds);
pen1.Dispose();
bounds.Inflate(1, 1);
}
}
This method will be called multi-times, each time for a cell in that column.
In this method, you will see that DataGridBoolColumn uses
ControlPaint.DrawCheckBox or ControlPaint.DrawMixedCheckBox to draw a
"Dummy" checkbox in cell.

We should apply the same thought to LinkLabel column, we should draw a
dummy linklabel in every non-edit cell. But because LinkLabel is not a
common control of Win32, so there is no build-in method in ControlPaint
class to draw LinkLabel control. However, linklabel's appearance is just a
blue color text string with underline. We may get this done with
FontStyle.UnderLine, someting like this:
protected override void OnPaint(PaintEventArgs e)
{
Font f=new Font(FontFamily.Families[0], (float)10.0, FontStyle.Underline);
e.Graphics.DrawString("Test", f, new SolidBrush(Color.Blue), 0, 0);
base.OnPaint(e);
}

There are a lot more work needs done in DataGridColumnStyle.Paint method,
my reply just gives you some thought on this. Hope this helps.
============================================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
G

Guest

Jeffrey,

Thank you for your reply. While it was somewhat helpful, I was hoping for a
little more in terms of code.

"Jeffrey Tan[MSFT]" said:
Hi Suz,

Thanks for your posting!!

Yes, just as Daisuke said, in .Net Framework, in a new control
DataGridView, there will be a build-in DataGridViewLinkColumn gives what
you need. But current now, the only supported build-in Columns are TextBox
and checkboxes.

If you want to implement a DataGridLinkLabelColumn yourself, seen from your
original post, I think your obstacle is: in non-edit mode, how is the
linkLabel displayed? I will clarify this for you:

Actually, for a DataGridColumnStyle, there is only one control in that
column, and in non-edit mode, the control will be invisible state. And it
will go into the edit mode cell when Edit protected method is invoked.(I
think you may have seen this in combobox sample). So for DataGridBoolColumn
etc, for DataGridCell that is not in edit mode, it is not actually a "TRUE"
checkbox control, DataGridBoolColumn just draws a dummy checkbox in every
non-edit mode cell. If we use Reflector to view DataGridBoolColumn.Paint
method, we will see:
protected internal override void Paint(Graphics g, Rectangle bounds,
CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush, bool
alignToRight)
{
object obj1 = (this.isEditing && (this.editingRow == rowNum)) ?
this.currentValue : this.GetColumnValueAtRow(source, rowNum);
ButtonState state1 = ButtonState.Inactive;
if (!Convert.IsDBNull(obj1))
{
state1 = ((bool) obj1) ? ButtonState.Checked :
ButtonState.Normal;
}
Rectangle rectangle1 = this.GetCheckBoxBounds(bounds, alignToRight);
Region region1 = g.Clip;
g.ExcludeClip(rectangle1);
Brush brush1 = this.DataGridTableStyle.IsDefault ?
this.DataGridTableStyle.DataGrid.SelectionBackBrush :
this.DataGridTableStyle.SelectionBackBrush;
if ((this.isSelected && (this.editingRow == rowNum)) &&
!this.IsReadOnly())
{
g.FillRectangle(brush1, bounds);
}
else
{
g.FillRectangle(backBrush, bounds);
}
g.Clip = region1;
if (state1 == ButtonState.Inactive)
{
ControlPaint.DrawMixedCheckBox(g, rectangle1,
ButtonState.Checked);
}
else
{
ControlPaint.DrawCheckBox(g, rectangle1, state1);
}
if ((this.IsReadOnly() && this.isSelected) && (source.Position ==
rowNum))
{
bounds.Inflate(-1, -1);
Pen pen1 = new Pen(brush1);
pen1.DashStyle = DashStyle.Dash;
g.DrawRectangle(pen1, bounds);
pen1.Dispose();
bounds.Inflate(1, 1);
}
}
This method will be called multi-times, each time for a cell in that column.
In this method, you will see that DataGridBoolColumn uses
ControlPaint.DrawCheckBox or ControlPaint.DrawMixedCheckBox to draw a
"Dummy" checkbox in cell.

We should apply the same thought to LinkLabel column, we should draw a
dummy linklabel in every non-edit cell. But because LinkLabel is not a
common control of Win32, so there is no build-in method in ControlPaint
class to draw LinkLabel control. However, linklabel's appearance is just a
blue color text string with underline. We may get this done with
FontStyle.UnderLine, someting like this:
protected override void OnPaint(PaintEventArgs e)
{
Font f=new Font(FontFamily.Families[0], (float)10.0, FontStyle.Underline);
e.Graphics.DrawString("Test", f, new SolidBrush(Color.Blue), 0, 0);
base.OnPaint(e);
}

There are a lot more work needs done in DataGridColumnStyle.Paint method,
my reply just gives you some thought on this. Hope this helps.
============================================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
M

Madhavi

I could find a solution for putting a LinkLabel on a datagrid cell. This is
what I have done in DataGridLinkLabelColumn(a class inherited from
DataGridTextBoxColumn) paint method. This may not be the best solution , but
it works for me

protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager
source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight)

{

lLabel = new LinkLabel();

DataGrid grid = (DataGrid)DataGridTableStyle.DataGrid;

lLabel.Text =
((DataTable)grid.DataSource).Rows[rowNum][this.MappingName].ToString();

lLabel.Bounds = bounds;

if( !grid.Controls.Contains(lLabel))

{

grid.Controls.Add(lLabel);

}


base.Paint(g,bounds,source,rowNum, backBrush, foreBrush, alignToRight);

lLabel.Update();

}



Thanks,

Madhavi

Suz said:
Jeffrey,

Thank you for your reply. While it was somewhat helpful, I was hoping for
a
little more in terms of code.

"Jeffrey Tan[MSFT]" said:
Hi Suz,

Thanks for your posting!!

Yes, just as Daisuke said, in .Net Framework, in a new control
DataGridView, there will be a build-in DataGridViewLinkColumn gives what
you need. But current now, the only supported build-in Columns are
TextBox
and checkboxes.

If you want to implement a DataGridLinkLabelColumn yourself, seen from
your
original post, I think your obstacle is: in non-edit mode, how is the
linkLabel displayed? I will clarify this for you:

Actually, for a DataGridColumnStyle, there is only one control in that
column, and in non-edit mode, the control will be invisible state. And it
will go into the edit mode cell when Edit protected method is invoked.(I
think you may have seen this in combobox sample). So for
DataGridBoolColumn
etc, for DataGridCell that is not in edit mode, it is not actually a
"TRUE"
checkbox control, DataGridBoolColumn just draws a dummy checkbox in every
non-edit mode cell. If we use Reflector to view DataGridBoolColumn.Paint
method, we will see:
protected internal override void Paint(Graphics g, Rectangle bounds,
CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush,
bool
alignToRight)
{
object obj1 = (this.isEditing && (this.editingRow == rowNum)) ?
this.currentValue : this.GetColumnValueAtRow(source, rowNum);
ButtonState state1 = ButtonState.Inactive;
if (!Convert.IsDBNull(obj1))
{
state1 = ((bool) obj1) ? ButtonState.Checked :
ButtonState.Normal;
}
Rectangle rectangle1 = this.GetCheckBoxBounds(bounds,
alignToRight);
Region region1 = g.Clip;
g.ExcludeClip(rectangle1);
Brush brush1 = this.DataGridTableStyle.IsDefault ?
this.DataGridTableStyle.DataGrid.SelectionBackBrush :
this.DataGridTableStyle.SelectionBackBrush;
if ((this.isSelected && (this.editingRow == rowNum)) &&
!this.IsReadOnly())
{
g.FillRectangle(brush1, bounds);
}
else
{
g.FillRectangle(backBrush, bounds);
}
g.Clip = region1;
if (state1 == ButtonState.Inactive)
{
ControlPaint.DrawMixedCheckBox(g, rectangle1,
ButtonState.Checked);
}
else
{
ControlPaint.DrawCheckBox(g, rectangle1, state1);
}
if ((this.IsReadOnly() && this.isSelected) && (source.Position ==
rowNum))
{
bounds.Inflate(-1, -1);
Pen pen1 = new Pen(brush1);
pen1.DashStyle = DashStyle.Dash;
g.DrawRectangle(pen1, bounds);
pen1.Dispose();
bounds.Inflate(1, 1);
}
}
This method will be called multi-times, each time for a cell in that
column.
In this method, you will see that DataGridBoolColumn uses
ControlPaint.DrawCheckBox or ControlPaint.DrawMixedCheckBox to draw a
"Dummy" checkbox in cell.

We should apply the same thought to LinkLabel column, we should draw a
dummy linklabel in every non-edit cell. But because LinkLabel is not a
common control of Win32, so there is no build-in method in ControlPaint
class to draw LinkLabel control. However, linklabel's appearance is just
a
blue color text string with underline. We may get this done with
FontStyle.UnderLine, someting like this:
protected override void OnPaint(PaintEventArgs e)
{
Font f=new Font(FontFamily.Families[0], (float)10.0,
FontStyle.Underline);
e.Graphics.DrawString("Test", f, new SolidBrush(Color.Blue), 0, 0);
base.OnPaint(e);
}

There are a lot more work needs done in DataGridColumnStyle.Paint method,
my reply just gives you some thought on this. Hope this helps.
============================================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to
be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no
rights.
 
G

Guest

Hi Madhavi!

That code looks pretty good. I will try it when I return to work on Monday.
Thanks so much!

Suz

Madhavi said:
I could find a solution for putting a LinkLabel on a datagrid cell. This is
what I have done in DataGridLinkLabelColumn(a class inherited from
DataGridTextBoxColumn) paint method. This may not be the best solution , but
it works for me

protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager
source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight)

{

lLabel = new LinkLabel();

DataGrid grid = (DataGrid)DataGridTableStyle.DataGrid;

lLabel.Text =
((DataTable)grid.DataSource).Rows[rowNum][this.MappingName].ToString();

lLabel.Bounds = bounds;

if( !grid.Controls.Contains(lLabel))

{

grid.Controls.Add(lLabel);

}


base.Paint(g,bounds,source,rowNum, backBrush, foreBrush, alignToRight);

lLabel.Update();

}



Thanks,

Madhavi

Suz said:
Jeffrey,

Thank you for your reply. While it was somewhat helpful, I was hoping for
a
little more in terms of code.

"Jeffrey Tan[MSFT]" said:
Hi Suz,

Thanks for your posting!!

Yes, just as Daisuke said, in .Net Framework, in a new control
DataGridView, there will be a build-in DataGridViewLinkColumn gives what
you need. But current now, the only supported build-in Columns are
TextBox
and checkboxes.

If you want to implement a DataGridLinkLabelColumn yourself, seen from
your
original post, I think your obstacle is: in non-edit mode, how is the
linkLabel displayed? I will clarify this for you:

Actually, for a DataGridColumnStyle, there is only one control in that
column, and in non-edit mode, the control will be invisible state. And it
will go into the edit mode cell when Edit protected method is invoked.(I
think you may have seen this in combobox sample). So for
DataGridBoolColumn
etc, for DataGridCell that is not in edit mode, it is not actually a
"TRUE"
checkbox control, DataGridBoolColumn just draws a dummy checkbox in every
non-edit mode cell. If we use Reflector to view DataGridBoolColumn.Paint
method, we will see:
protected internal override void Paint(Graphics g, Rectangle bounds,
CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush,
bool
alignToRight)
{
object obj1 = (this.isEditing && (this.editingRow == rowNum)) ?
this.currentValue : this.GetColumnValueAtRow(source, rowNum);
ButtonState state1 = ButtonState.Inactive;
if (!Convert.IsDBNull(obj1))
{
state1 = ((bool) obj1) ? ButtonState.Checked :
ButtonState.Normal;
}
Rectangle rectangle1 = this.GetCheckBoxBounds(bounds,
alignToRight);
Region region1 = g.Clip;
g.ExcludeClip(rectangle1);
Brush brush1 = this.DataGridTableStyle.IsDefault ?
this.DataGridTableStyle.DataGrid.SelectionBackBrush :
this.DataGridTableStyle.SelectionBackBrush;
if ((this.isSelected && (this.editingRow == rowNum)) &&
!this.IsReadOnly())
{
g.FillRectangle(brush1, bounds);
}
else
{
g.FillRectangle(backBrush, bounds);
}
g.Clip = region1;
if (state1 == ButtonState.Inactive)
{
ControlPaint.DrawMixedCheckBox(g, rectangle1,
ButtonState.Checked);
}
else
{
ControlPaint.DrawCheckBox(g, rectangle1, state1);
}
if ((this.IsReadOnly() && this.isSelected) && (source.Position ==
rowNum))
{
bounds.Inflate(-1, -1);
Pen pen1 = new Pen(brush1);
pen1.DashStyle = DashStyle.Dash;
g.DrawRectangle(pen1, bounds);
pen1.Dispose();
bounds.Inflate(1, 1);
}
}
This method will be called multi-times, each time for a cell in that
column.
In this method, you will see that DataGridBoolColumn uses
ControlPaint.DrawCheckBox or ControlPaint.DrawMixedCheckBox to draw a
"Dummy" checkbox in cell.

We should apply the same thought to LinkLabel column, we should draw a
dummy linklabel in every non-edit cell. But because LinkLabel is not a
common control of Win32, so there is no build-in method in ControlPaint
class to draw LinkLabel control. However, linklabel's appearance is just
a
blue color text string with underline. We may get this done with
FontStyle.UnderLine, someting like this:
protected override void OnPaint(PaintEventArgs e)
{
Font f=new Font(FontFamily.Families[0], (float)10.0,
FontStyle.Underline);
e.Graphics.DrawString("Test", f, new SolidBrush(Color.Blue), 0, 0);
base.OnPaint(e);
}

There are a lot more work needs done in DataGridColumnStyle.Paint method,
my reply just gives you some thought on this. Hope this helps.
============================================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to
be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no
rights.
 
J

Jeffrey Tan[MSFT]

Hi Suz,

Thanks for your feedback!!

Actually, we can leverage the implementation of normal
DataGridComboBoxColumn class(Which there are many sample code in internet).
Below is a sample implementation of DataGridComboBoxColumn class:
http://www.syncfusion.com/faq/winforms/search/480.asp

In the sample code, what we should do is just change the control from
ComboBox to LinkLabel control(certainly there will be some more extra
modification work) and add some additional code in the Paint method. For
paint code, I think Madhavi has provided you sample code snippet which
gives a good example on how to do the cell painting in Paint method.

Anyway, if you need further help or have any further concern, please feel
free to tell us. Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Suz,

Have you tried the code snippet? Is your problem resolved? Please feel free
to tell us. Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 

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