我的表单上有一个PropertyGrid.我的老板认为这很难看.粗野.性格单纯.
他想要一个漂亮,整洁,干净的形式.这是一个问题:其中一个属性是我们自己种植的物品的集合.他喜欢这个系列的收藏编辑器.
我知道我可以建立自己的收藏编辑器.但有没有一个干净,简单的解决方案来节省我几个小时的编码,这样我可以直接创建和使用Collection编辑器而无需使用属性网格?
你可以从UITypeEditor
(via TypeDescriptor
)获得这个功能,但这不是一件容易的事 - 你需要设置一个IServiceProvider
,一个IWindowsFormsEditorService
,理想的是ITypeDescriptorContext
- 相当一点.如果您不熟悉这些工具,手动操作可能会更简单.
或者 - 看看SmartPropertyGrid.NET,替代PropertyGrid
.
更新:这是一个工作示例......绝对不是一件容易的事,但随意窃取代码.它仅适用于模态编辑器,而不适用于下拉列表.它也不是"关注点分离"的一个很好的例子.这MyHelper
堂课很有意思.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing.Design; using System.Windows.Forms; using System.Windows.Forms.Design; class Foo { public Foo() { Bars = new List(); } public List Bars { get; private set; } } class Bar { public string Name { get; set; } public DateTime DateOfBirth { get; set; } } static class Program { [STAThread] static void Main() { Foo foo = new Foo(); Bar bar = new Bar(); bar.Name = "Fred"; bar.DateOfBirth = DateTime.Today; foo.Bars.Add(bar); Application.EnableVisualStyles(); using(Form form = new Form()) using (Button btn = new Button()) { form.Controls.Add(btn); btn.Text = "Edit"; btn.Click += delegate { MyHelper.EditValue(form, foo, "Bars"); }; Application.Run(form); } } } class MyHelper : IWindowsFormsEditorService, IServiceProvider, ITypeDescriptorContext { public static void EditValue(IWin32Window owner, object component, string propertyName) { PropertyDescriptor prop = TypeDescriptor.GetProperties(component)[propertyName]; if(prop == null) throw new ArgumentException("propertyName"); UITypeEditor editor = (UITypeEditor) prop.GetEditor(typeof(UITypeEditor)); MyHelper ctx = new MyHelper(owner, component, prop); if(editor != null && editor.GetEditStyle(ctx) == UITypeEditorEditStyle.Modal) { object value = prop.GetValue(component); value = editor.EditValue(ctx, ctx, value); if (!prop.IsReadOnly) { prop.SetValue(component, value); } } } private readonly IWin32Window owner; private readonly object component; private readonly PropertyDescriptor property; private MyHelper(IWin32Window owner, object component, PropertyDescriptor property) { this.owner = owner; this.component = component; this.property = property; } #region IWindowsFormsEditorService Members public void CloseDropDown() { throw new NotImplementedException(); } public void DropDownControl(System.Windows.Forms.Control control) { throw new NotImplementedException(); } public System.Windows.Forms.DialogResult ShowDialog(System.Windows.Forms.Form dialog) { return dialog.ShowDialog(owner); } #endregion #region IServiceProvider Members public object GetService(Type serviceType) { return serviceType == typeof(IWindowsFormsEditorService) ? this : null; } #endregion #region ITypeDescriptorContext Members IContainer ITypeDescriptorContext.Container { get { return null; } } object ITypeDescriptorContext.Instance { get { return component; } } void ITypeDescriptorContext.OnComponentChanged() {} bool ITypeDescriptorContext.OnComponentChanging() { return true; } PropertyDescriptor ITypeDescriptorContext.PropertyDescriptor { get { return property; } } #endregion }