我有一个 DataGridView 可以正常工作,显示数据如下:
private DataGridView dgv;
private List<Item> Items = new();
Items.Add(new() {ID = 1, Service = new() { Name = "Item 1"}, Quantity = 2});
dgv.DataSource = Items;
// [...]
Public Class Item
{
public int ID {get; set;}
public Service Service {get; set;}
public int Quantity {get; set;}
}
Public Class Service
{
public string Name {get; set;}
Public overrides string To string => Name;
}
在我介绍之前一切都工作得很好
public interface IService
{
public string Name {get; set;}
}
然后改变:
public Service Service {get; set;}
致:
public IService Service {get; set;}
然后让
Service
类实现该接口:
public class Service: IService...
一切仍然有效,除了 DataGridView 中的
Service
列什么都不显示,尽管当我用鼠标悬停在它上面时我可以看到值
当 DataGridView 需要格式化 Cell 的值以进行演示时,它会对底层 Type 执行一系列(长)测试。
然后,它调用类型的默认格式化程序,因此您可以覆盖类对象中的
ToString()
,以返回格式化值。
当底层类型是接口时,它会验证是否实现了IFormattable。如果不是,那么
FormattedValue
就是 null
。
另请参阅此处的注释:
DataGridView HeaderCell 为数字类型时不显示值
鉴于当前的结构:
public class Item {
public int ID { get; set; }
public IService? Service { get; set; } = null;
public int Quantity { get; set; }
}
public class Service : IService {
public string Name { get; set; } = string.Empty;
public override string ToString() => Name;
}
public interface IService {
string Name { get; set; }
}
您可以做几件事:
如果需要保持类的结构不变,则处理 CellFormatting 事件并将 Cell 的 Value 设置为当前
e.Value
(Service
对象),转换为字符串,即 e.Value.ToString()
:
private void dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) {
var dgv = sender as DataGridView;
if (dgv?.Columns[e.ColumnIndex].Name == nameof(Service)) {
e.Value = e.Value?.ToString();
}
// Or...
if (e.Value?.GetType() == typeof(Service)) {
e.Value = e.Value?.ToString();
}
}
如果您可以更改 Service 类,则实现 IFormattable。如果不需要其他格式(例如,您需要考虑特定的文化或格式),您可以使其
ToString()
实现仅调用现有的 ToString()
覆盖:
public class Service : IService, IFormattable {
public string Name { get; set; } = string.Empty;
public override string ToString() => Name;
public string ToString(string? format, IFormatProvider? provider) => ToString();
}
在这种情况下,您不需要处理
CellFormatting
。Service
列的 Format属性设置为通用格式,例如:
dgv.Columns["Service"].DefaultCellStyle.Format = "G";
DataGridView 会检查类对象是否实现了 IFormattable,如果实现则调用其方法。