EPiServer后台Property List能否自定义外观优化UI显示?
Hey there, totally get your frustration—those default displays for Property List components can feel pretty unhelpful for editors, especially when you’re just getting started with EPiServer. Let’s break down how to fix both your image and URL display problems step by step.
1. Improving Image Property Display (Replace Content ID with Thumbnail/Name)
By default, EPiServer renders ContentReference values (like your image property) as raw IDs in the Property List table. To make this editor-friendly, we’ll create a custom column renderer to load the image content and display a thumbnail or its name.
Step 1: Create a Custom Property List Column Factory
Create a class that implements IPropertyListColumnFactory to override how image properties are rendered:
using EPiServer.Core; using EPiServer.ServiceLocation; using EPiServer.Shell.ObjectEditing.EditorDescriptors; using EPiServer.Web.Routing; using System.Collections.Generic; using System.Linq; [ServiceConfiguration(typeof(IPropertyListColumnFactory))] public class CustomPropertyListColumnFactory : IPropertyListColumnFactory { private readonly IContentLoader _contentLoader; private readonly UrlResolver _urlResolver; public CustomPropertyListColumnFactory(IContentLoader contentLoader, UrlResolver urlResolver) { _contentLoader = contentLoader; _urlResolver = urlResolver; } public IEnumerable<PropertyListColumn> CreateColumns(ExtendedMetadata metadata) { foreach (var property in metadata.Properties) { // Target image properties marked with UIHint.Image if (property.PropertyType == typeof(ContentReference) && property.Attributes.OfType<UIHintAttribute>().Any(h => h.UIHint == UIHint.Image)) { yield return new PropertyListColumn { Header = property.DisplayName, Renderer = (item) => { var contentReference = item.GetPropertyValue<ContentReference>(property.Name); if (ContentReference.IsNullOrEmpty(contentReference)) { return "-"; } if (_contentLoader.TryGet<ImageData>(contentReference, out var image)) { // Render a small thumbnail + image name for clarity var imageUrl = _urlResolver.GetUrl(image.ContentLink); return $"<img src=\"{imageUrl}?width=50\" alt=\"{image.Name}\" style=\"vertical-align: middle; margin-right: 8px;\">{image.Name}"; } return contentReference.ToString(); } }; } // Handle URL properties next else if (property.PropertyType == typeof(Url) || (property.PropertyType == typeof(ContentReference) && property.Attributes.OfType<UIHintAttribute>().Any(h => h.UIHint == UIHint.URL))) { yield return new PropertyListColumn { Header = property.DisplayName, Renderer = (item) => { if (property.PropertyType == typeof(Url)) { var url = item.GetPropertyValue<Url>(property.Name); if (url?.IsEmpty != true) { // Convert internal URLs to friendly format if (url.IsInternal) { return _urlResolver.GetFriendlyUrl(url.ContentReference); } return url.ToString(); } } else if (property.PropertyType == typeof(ContentReference)) { var contentReference = item.GetPropertyValue<ContentReference>(property.Name); if (!ContentReference.IsNullOrEmpty(contentReference)) { return _urlResolver.GetFriendlyUrl(contentReference); } } return "-"; } }; } // Fallback to default rendering for all other properties else { yield return new PropertyListColumn { Header = property.DisplayName, Renderer = (item) => item.GetPropertyValue(property.Name)?.ToString() ?? "-" }; } } } }
Step 2: Register the Factory
The [ServiceConfiguration] attribute automatically registers this factory with EPiServer’s dependency injection system—no extra setup needed here. Just build your project and clear the EPiServer cache to see changes.
Key Tips for New EPiServer Users
- Mark your model properties with the right UI hints to help the factory target them:
[UIHint(UIHint.Image)] public ContentReference HeroImage { get; set; } [UIHint(UIHint.URL)] public Url LinkUrl { get; set; } - If you’re using a custom image type (instead of the default
ImageData), update the_contentLoader.TryGet<YourCustomImageType>line to match your class. - Test this in a development environment first, and use the EPiServer admin mode’s cache clear tool to refresh the backend UI quickly.
This setup will make the Property List table way more intuitive for your editors—no more squinting at Content IDs or decoding messy internal URLs!
内容的提问来源于stack exchange,提问作者Ayo Adesina

