C#如何让ListBox显示List<Entity>的指定字段(如PublisherID等)
解决ListBox显示Solution指定字段的问题
你的问题在于直接绑定List<Entity>到ListBox时,默认会显示Entity类型的ToString结果(也就是实体的类型名称),而不是你需要的字段信息。这里有两种常用的解决方案,根据你的需求选择:
方法1:创建ViewModel封装数据(推荐)
这种方式更清晰,也便于后续扩展,把需要展示的字段封装到一个自定义类中,还能灵活控制显示内容:
首先定义一个SolutionViewModel类,提取你需要的字段并重写ToString方法(让ListBox直接显示组合信息):
public class SolutionViewModel { public string FriendlyName { get; set; } public string PublisherName { get; set; } public DateTime InstalledOn { get; set; } public string Version { get; set; } public string UniqueName { get; set; } // 重写ToString,自定义ListItem的显示内容 public override string ToString() { return $"[{FriendlyName}] | Publisher: {PublisherName} | Version: {Version} | Installed: {InstalledOn:yyyy-MM-dd}"; } }
然后修改你的getAllSolutions方法,把Entity转换为SolutionViewModel:
public static class SolutionActions { public static List<SolutionViewModel> getAllSolutions(IOrganizationService _serviceProxy) { QueryExpression querySampleSolution = new QueryExpression { EntityName = "solution", ColumnSet = new ColumnSet(new string[] { "publisherid", "installedon", "version", "versionnumber", "friendlyname", "uniquename" }), Criteria = new FilterExpression(), NoLock = true, }; EntityCollection foundSolutions = _serviceProxy.RetrieveMultiple(querySampleSolution); // 将Entity转换为ViewModel,注意publisherid是EntityReference类型,取它的Name属性 return foundSolutions.Entities.Select(entity => new SolutionViewModel { FriendlyName = entity.GetAttributeValue<string>("friendlyname"), PublisherName = entity.GetAttributeValue<EntityReference>("publisherid")?.Name ?? "Unknown Publisher", InstalledOn = entity.GetAttributeValue<DateTime>("installedon"), Version = entity.GetAttributeValue<string>("version"), UniqueName = entity.GetAttributeValue<string>("uniquename") }).ToList(); } }
最后修改绑定代码:
if (sourceConnection != null) { List<SolutionViewModel> foundSolutions = SolutionActions.getAllSolutions(sourceConnection._orgService); listSolutions.DataSource = foundSolutions; }
方法2:利用ListBox的Format事件(无需额外类)
如果不想创建新类,可以通过处理ListBox的Format事件来动态设置每个项的显示内容:
先绑定数据,然后注册事件:
if (sourceConnection != null) { List<Entity> foundSolutions = SolutionActions.getAllSolutions(sourceConnection._orgService); listSolutions.DataSource = foundSolutions; // 注册Format事件 listSolutions.Format += ListSolutions_Format; }
然后实现事件处理方法:
private void ListSolutions_Format(object sender, ListControlConvertEventArgs e) { if (e.ListItem is Entity solutionEntity) { // 提取各个字段的值,注意处理可能的空值 string friendlyName = solutionEntity.GetAttributeValue<string>("friendlyname") ?? "Unnamed Solution"; string publisherName = solutionEntity.GetAttributeValue<EntityReference>("publisherid")?.Name ?? "Unknown Publisher"; DateTime installedOn = solutionEntity.GetAttributeValue<DateTime>("installedon"); string version = solutionEntity.GetAttributeValue<string>("version") ?? "Unknown Version"; // 自定义显示的文本格式 e.Value = $"Solution: {friendlyName} | Publisher: {publisherName} | Version: {version} | Installed Date: {installedOn:yyyy-MM-dd HH:mm}"; } }
关键注意点
publisherid是EntityReference类型,不能直接取字符串,必须访问它的Name属性才能得到出版商的名称;- 记得处理可能的空值(比如有些字段可能未设置),避免空引用异常;
- 如果是WPF项目,你还可以通过设置
ItemTemplate来更灵活地控制UI布局,不过从你的代码风格来看更偏向WinForms,所以上面的方案更适配。
内容的提问来源于stack exchange,提问作者Melon Man
相关产品推荐
相关产品推荐

