Ah, what the heck... ;-p
Note this draws on Carsten Zeumer's CodeProject example
(PropertyGridExWinForms).
Marc
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Text;
using System.Windows.Forms;
// sample entity class
public class Foo : IDataErrorInfo
{
public string Name { get; set; }
[DisplayName("Date of Birth")]
public DateTime DateOfBirth { get; set; }
string IDataErrorInfo.Error
{
get { return null; }
}
private static void AddError(ref StringBuilder sb, string message) {
if(!string.IsNullOrEmpty(message)) {
if(sb == null) sb = new StringBuilder();
sb.AppendLine(message);
}
}
string IDataErrorInfo.this[string columnName]
{
get {
StringBuilder err = null;
switch (columnName)
{
case "Name":
if (string.IsNullOrEmpty(Name)) AddError(ref err,
"Name cannot be blank");
break;
case "DateOfBirth":
if (DateOfBirth == DateTime.MinValue) AddError(ref
err, "Date of Birth cannot be blank");
if (DateOfBirth > DateTime.Now) AddError(ref err,
"Date of Birth cannot be in the future");
break;
}
return err == null ? null : err.ToString();
}
}
}
static class Program
{
// used to show error notifications
private static readonly PropertyValueUIItemInvokeHandler
UIItemNullHandler = delegate { };
private static readonly Image UIItemErrorImage =
SystemIcons.Error.ToBitmap();
static void VerifyDataErrorInfo(ITypeDescriptorContext context,
PropertyDescriptor propDesc, ArrayList valueUIItemList)
{
IDataErrorInfo errInfo = context == null ? null :
context.Instance as IDataErrorInfo;
string propName = propDesc == null ? null : propDesc.Name;
if(errInfo != null && !string.IsNullOrEmpty(propName)) {
string errMsg = errInfo[propName];
if(!string.IsNullOrEmpty(errMsg)) {
valueUIItemList.Add(new
PropertyValueUIItem(UIItemErrorImage, UIItemNullHandler, errMsg));
}
}
}
// sample app
static void Main() {
Foo foo = new Foo();
Application.EnableVisualStyles();
using(Form form = new Form())
using (PropertyGrid grid = new PropertyGrid())
{
SimpleSite site = new SimpleSite
{
Name = "GridSite",
Component = grid
};
GlyphService svc = new GlyphService();
svc.QueryPropertyUIValueItems += VerifyDataErrorInfo;
site.AddService<IPropertyValueUIService>(svc);
grid.Site = site;
grid.Dock = DockStyle.Fill;
grid.SelectedObject = foo;
form.Controls.Add(grid);
Application.Run(form);
}
}
}
public sealed class GlyphService : IPropertyValueUIService
{
public event EventHandler PropertyUIValueItemsChanged;
public event PropertyValueUIHandler QueryPropertyUIValueItems;
public PropertyValueUIItem[]
GetPropertyUIValueItems(ITypeDescriptorContext context,
PropertyDescriptor propDesc)
{
ArrayList list = null;
if (QueryPropertyUIValueItems != null)
{
list = new ArrayList();
QueryPropertyUIValueItems(context, propDesc, list);
}
if (list == null || list.Count == 0)
{
return new PropertyValueUIItem[0];
}
PropertyValueUIItem[] result = new PropertyValueUIItem[list.Count];
list.CopyTo(result);
return result;
}
public void NotifyPropertyValueUIItemsChanged()
{
if (PropertyUIValueItemsChanged != null)
{
PropertyUIValueItemsChanged(this, EventArgs.Empty);
}
}
void
IPropertyValueUIService.RemovePropertyValueUIHandler(PropertyValueUIHandler
newHandler)
{
QueryPropertyUIValueItems -= newHandler;
}
void
IPropertyValueUIService.AddPropertyValueUIHandler(PropertyValueUIHandler
newHandler)
{
QueryPropertyUIValueItems += newHandler;
}
}
public sealed class SimpleSite : ISite, IServiceProvider
{
public IComponent Component { get; set; }
private readonly IContainer container = new Container();
IContainer ISite.Container { get { return container; } }
public bool DesignMode {get;set;}
public string Name {get;set;}
private Dictionary<Type, object> services;
public void AddService<T>(T service) where T : class
{
if (services == null) services = new Dictionary<Type, object>();
services[typeof(T)] = service;
}
public void RemoveService<T>() where T : class
{
if (services != null) services.Remove(typeof(T));
}
object IServiceProvider.GetService(Type serviceType)
{
object service;
if (services != null && services.TryGetValue(serviceType, out
service))
{
return service;
}
return null;
}
}