SelectionForeColor not working for link cells in DataGridViewLinkColumn of DataGridView

1.5k Views Asked by At

In my Winform 4.5 app, I have a DataGridView with first column as a link column. I would like to have the link color of the selected link cell to be white. Since by default the background color of a selected row (or a cell) is blue and the ForeColor of all the links are also blue, when user selects a row (or a link cell) the text of the link is not readable. I tried writing the following code but it does not change the link color of selected link cell at all.

private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
    foreach (DataGridViewLinkCell cell in ((DataGridView)sender).SelectedCells)
    {
        if (cell.ColumnIndex == 0)
        {
            if (cell.Selected)
            {
                cell.Style = new DataGridViewCellStyle()
                {
                    SelectionForeColor = SystemColors.HighlightText
                };
            }
        }
    }
}

I then modified the above code as follows. But it changes the link color of all the links to white - that makes non-selected link cells to be not readable since the backcolor of those links is also white:

private void dataGridView1_SelectionChanged(object sender, EventArgs e)
    {
        foreach (DataGridViewLinkCell cell in ((DataGridView)sender).SelectedCells)
        {
            if (cell.ColumnIndex == 0)
            {
                if (cell.Selected)
                {
                    cell.LinkColor = SystemColors.HighlightText;
                }
            }
        }
    }

I tested both the codes by setting a breakpoint inside the foreach loop and selecting a link cell. I noticed that the code does go through exactly one iteration of the foreach loop correctly. Moreover, I have made no change to the default settings of the DataGridViewLinkColumn

Edit By default the DataGridView looks like this on a row selection. Notice that the cell in the second column changes its ForeColor to white but not the cell in the first column: enter image description here


I want it to looks like this on a row selection: enter image description here

2

There are 2 best solutions below

5
On

Edit The CellLeave event will always occur when an attempt is made to navigate away from a cell.

    private void dataGridView1_SelectionChanged(object sender, EventArgs e)
    {
        foreach (DataGridViewLinkCell cell in 
            ((DataGridView) sender).SelectedCells.OfType<DataGridViewLinkCell>())
        {
            if (cell.Selected)
            {
                cell.LinkColor = SystemColors.HighlightText;
            }
        }

    }

    private void dataGridView1_CellLeave(object sender, DataGridViewCellEventArgs e)
    {
        foreach (DataGridViewLinkCell cell in
            ((DataGridView) sender).Rows[e.RowIndex].Cells.OfType<DataGridViewLinkCell>())
        {
            cell.LinkColor = cell.LinkVisited ? Color.Purple : Color.Blue;
        }
    }

Result

0
On

I've experienced the same issue and I got it working using the CellFormatting event. Below you'll find a generic solution for this:

void grd_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    SetGridLinkColor(sender as DataGridView, e.RowIndex, e.ColumnIndex, Color.White);
}

public static void SetGridLinkColor(DataGridView grd, int rowIndex, int columnIndex, Color selectedColor)
{
  if (grd == null || !(grd.Columns[columnIndex] is DataGridViewLinkColumn))
    return;

  if (grd.Rows[rowIndex].Selected)
  {
    ((DataGridViewLinkCell)grd.Rows[rowIndex].Cells[columnIndex]).LinkColor = selectedColor;
    ((DataGridViewLinkColumn)grd.Columns[columnIndex]).VisitedLinkColor = selectedColor;
  }
  else
  {
    Color color = ((DataGridViewLinkColumn)grd.Columns[columnIndex]).LinkColor;
    ((DataGridViewLinkCell)grd.Rows[rowIndex].Cells[columnIndex]).LinkColor = color;
    ((DataGridViewLinkColumn)grd.Columns[columnIndex]).VisitedLinkColor = color;
  }
}