在Winforms DataGridView中如何给单元格添加超链接

20

我有一个包含以下数据的DataGridView。

ContactType        |        Contact
------------------------------------
Phone              |       894356458
Email              |     xyz@abc.com

我需要将数据 "xyz@abc.com" 以超链接的形式显示,并添加一个提示 "点击发送电子邮件"。数字数据 "894356458" 不应该有超链接。

有什么想法吗?

TIA!


我已经编辑了我的答案,解释了如何更好地在您的情况下使用我的第一个选项(通过隐藏一列并使用DataPropertyName),并提供了第二个变体的答案,其中保留文本列。 - David Hall
2个回答

27
< p > DataGridView 已经为此提供了一种列类型,即 DataGridViewLinkColumn

您需要手动绑定此列类型,其中 DataPropertyName 设置要绑定到网格数据源中的列:

DataGridViewLinkColumn col = new DataGridViewLinkColumn();
col.DataPropertyName = "Contact";
col.Name = "Contact";       
dataGridView1.Columns.Add(col);
你还需要隐藏来自网格联系人属性的自动生成文本列。
另外,与 DataGridViewButtonColumn 类似,您需要通过响应 CellContentClick 事件来处理用户交互。
要将非超链接单元格值更改为纯文本,您需要使用文本框单元格替换链接单元格类型。在下面的示例中,我在 DataBindingComplete 事件期间执行了此操作:
void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
    foreach (DataGridViewRow r in dataGridView1.Rows)
    {
        if (!System.Uri.IsWellFormedUriString(r.Cells["Contact"].Value.ToString(), UriKind.Absolute))
        {
            r.Cells["Contact"] = new DataGridViewTextBoxCell();
        }
    }
}
你也可以从另一个方向去做,将DataGridViewTextBoxCell改为DataGridViewLinkCell。我建议你采用这种方法,因为你需要将所有链接的更改应用到每个单元格上。尽管如此,这种方法有一个优点,那就是你不需要隐藏自动生成的列,所以可能更适合你。
void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
    foreach (DataGridViewRow r in dataGridView1.Rows)
    {
        if (System.Uri.IsWellFormedUriString(r.Cells["Contact"].Value.ToString(), UriKind.Absolute))
        {
            r.Cells["Contact"] = new DataGridViewLinkCell();
            // Note that if I want a different link colour for example it must go here
            DataGridViewLinkCell c = r.Cells["Contact"] as DataGridViewLinkCell;
            c.LinkColor = Color.Green;
        }
    }
}

或者,你能不能反过来做呢?默认情况下将网格定义为TextBoxCell,然后在每行中超链接所需的单元格?只是想知道为什么你默认使用LinkCells,然后明确地改回TextBox。 - B L
1
@ Brett,超链接列具有一些额外的属性和行为非常方便,例如已访问链接颜色和TrackVisitedState - 当然你可以用另一种方式实现,但我认为这种方法更方便。 - David Hall
1
这个解决方案听起来不错。但是这个gridview的数据源是一个List<myClass>,其中myClass具有属性-ContactType、Contact。所以只需将数据源设置为gridview即可。我不会在这里手动添加行和列。在这种情况下,我们该如何解决这个问题? - Sandeep
@Brett,我刚刚加入了我认为你在建议的内容。这符合你的想法吗?对我来说,这都是无所谓的,我之前给出的答案是因为我将其视为具有纯文本的链接列,而不是具有链接的文本列。所以当然感谢你的问题让我思考更多! :) - David Hall
@David - 我并不是完全反对你的方法,我只是好奇因为我自己没有想到过这种做法,所以我想知道你从中获得了什么。抱歉造成了误解,但是我指的是使用设计师来驱动结构,因为这样不会破坏绑定,因为他可能正在执行类似于“dataGridView.DataSource = List<class>”的操作来检索信息。 - B L
显示剩余5条评论

1

你可以更改DataGridView中整列的样式。这也是将列变为链接列的方法之一。

DataGridViewCellStyle cellStyle = new DataGridViewCellStyle();
        cellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
        cellStyle.ForeColor = Color.LightBlue;
        cellStyle.SelectionForeColor = Color.Black;
        cellStyle.Font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Underline);
        dataGridView.Columns[1].DefaultCellStyle = cellStyle;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接