'DataGridviewLinkCell - Change the fore color of highlighted cell

I have a datagridview with 1 column being of type DataGridviewLinkColumn, the link text is in blue color and when the focus is on a cell the background color of the cell is also in blue color which makes it hard to read the cell value.

using the below link ,I tried changing the text background color to white when the focus is on that cell and it works fine as expected.

SelectionForeColor not working for link cells in DataGridViewLinkColumn of DataGridView

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;
    }
}

However when the data is loaded into the Datagridview by default there is focus on the 1st cell i.e Cell[0] in Row[0] , in this case the fore color does not change to white, once i start changing the cell focus it works.

In the initial state how can i set the DataGridviewLinkColumn text color to white when the focus is by default ?

Also when i change the focus to any other control outside of datagridview the highlighted cell link text color change back to blue.



Solution 1:[1]

Extend the DataGridViewLinkCell class and then set the LinkColor if the cellState is currently selected.

E.g:

public class DataGridViewLinkCell2 : DataGridViewLinkCell {

    private static PropertyInfo piVisitedLinkColorInternal = null;
    private static PropertyInfo piLinkColorInternal = null;

    static DataGridViewLinkCell2() {
        // use reflection, otherwise setting the properties directly calls InvalidateCell(...)
        // or InvalidateColumn(...) which results in an infinite loop of screen refreshing
        Type ty = typeof(DataGridViewLinkCell);
        piVisitedLinkColorInternal = ty.GetProperty("VisitedLinkColorInternal", BindingFlags.SetProperty | BindingFlags.NonPublic | BindingFlags.Instance);
        piLinkColorInternal = ty.GetProperty("LinkColorInternal", BindingFlags.SetProperty | BindingFlags.NonPublic | BindingFlags.Instance);
    }

    protected override void Paint(Graphics g, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) {
        Color origLinkColor = this.LinkColor;
        Color origVisitedLinkColor = this.VisitedLinkColor;
        if (cellState == (cellState | DataGridViewElementStates.Selected)) {
            Color c = cellStyle.SelectionForeColor;
            piLinkColorInternal.SetValue(this, c);
            piVisitedLinkColorInternal.SetValue(this, c);
        }

        base.Paint(g, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
        // put back original, otherwise cells that were previously selected keep the new color
        piLinkColorInternal.SetValue(this, origLinkColor);
        piVisitedLinkColorInternal.SetValue(this, origVisitedLinkColor);
    }
}


        var colLink = new DataGridViewLinkColumn { Name = "Blah", DataPropertyName = "Blah" };
        colLink.CellTemplate = new DataGridViewLinkCell2();

        DataGridView dgv = new DataGridView { Dock = DockStyle.Fill };
        dgv.AutoGenerateColumns = false;
        dgv.Columns.Add(colLink);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1