C# 在不使用属性网格控件的情况下使用.NET集合编辑器
我的表格上有一个PropertyGrid。我老板认为这很难看。粗俗的纯朴的 他想要一张漂亮、整洁、干净的表格。这里有一个陷阱:其中一个属性是我们自己生成的对象的集合。他喜欢这个收藏的编辑C# 在不使用属性网格控件的情况下使用.NET集合编辑器,c#,.net,collections,propertygrid,C#,.net,Collections,Propertygrid,我的表格上有一个PropertyGrid。我老板认为这很难看。粗俗的纯朴的 他想要一张漂亮、整洁、干净的表格。这里有一个陷阱:其中一个属性是我们自己生成的对象的集合。他喜欢这个收藏的编辑 我知道我可以建立自己的收藏编辑器。但是,有没有一个干净、简单的解决方案可以为我节省几个小时的编码时间,这样我就可以直接创建和使用集合编辑器而不必使用属性网格?您可以从UITypeEditor(通过TypeDescriptor)获得此功能,但这并不简单-您需要设置一个iSeries Provider,一个iInd
我知道我可以建立自己的收藏编辑器。但是,有没有一个干净、简单的解决方案可以为我节省几个小时的编码时间,这样我就可以直接创建和使用集合编辑器而不必使用属性网格?您可以从
UITypeEditor
(通过TypeDescriptor
)获得此功能,但这并不简单-您需要设置一个iSeries Provider
,一个iIndowsFormsEditor服务
,理想情况下是一个ITypeDescriptorContext
——相当多的垃圾。如果您不熟悉这些工具,那么手工操作可能更简单
或者-看看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<Bar>(); }
public List<Bar> 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
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统、绘图、设计;
使用System.Windows.Forms;
使用System.Windows.Forms.Design;
福班
{
public Foo(){bar=new List();}
公共列表栏{get;private set;}
}
分类栏
{
公共字符串名称{get;set;}
公共日期时间出生日期{get;set;}
}
静态类程序
{
[状态线程]
静态void Main()
{
Foo-Foo=新的Foo();
条形=新条形();
bar.Name=“Fred”;
bar.DateOfBirth=DateTime.Today;
foo.bar.Add(bar);
Application.EnableVisualStyles();
使用(表单=新表单())
使用(按钮btn=新按钮())
{
表单.控件.添加(btn);
btn.Text=“编辑”;
点击+=委托
{
EditValue(form,foo,“bar”);
};
申请表格;
}
}
}
类MyHelper:IWINDOWSFormsEditor服务、IServiceProvider、ITypeDescriptorContext
{
公共静态void EditValue(iwin32窗口所有者、对象组件、字符串propertyName){
PropertyDescriptor prop=TypeDescriptor.GetProperties(组件)[propertyName];
如果(prop==null)抛出新的ArgumentException(“propertyName”);
UITypeEditor=(UITypeEditor)prop.GetEditor(typeof(UITypeEditor));
MyHelper ctx=新的MyHelper(所有者、组件、道具);
if(editor!=null&&editor.GetEditStyle(ctx)==UITypeEditorEditStyle.Modal)
{
对象值=prop.GetValue(组件);
value=editor.EditValue(ctx,ctx,value);
如果(!prop.IsReadOnly)
{
属性设置值(组件、值);
}
}
}
私有只读iwin32窗口所有者;
私有只读对象组件;
私有只读属性Descriptor属性;
私有MyHelper(iwin32窗口所有者、对象组件、PropertyDescriptor属性)
{
this.owner=所有者;
这个组件=组件;
this.property=属性;
}
#地区iIndowsFormsEditor服务成员
公共无效关闭下拉列表()
{
抛出新的NotImplementedException();
}
公共void下拉控件(System.Windows.Forms.Control)
{
抛出新的NotImplementedException();
}
public System.Windows.Forms.DialogResult ShowDialog(System.Windows.Forms.Form对话框)
{
返回对话框。ShowDialog(所有者);
}
#端区
#区域IServiceProvider成员
公共对象GetService(类型serviceType)
{
return serviceType==typeof(IWindowsFormsEditorService)?此项:空;
}
#端区
#区域ITypeDescriptorContext成员
IContainer ITypeDescriptorContext.Container
{
获取{return null;}
}
对象ITypeDescriptorContext.Instance
{
获取{return component;}
}
void ITypeDescriptorContext.OnComponentChanged()无效
{}
bool ITypeDescriptorContext.onComponentChangeing()
{
返回true;
}
PropertyDescriptor ITypeScriptorContext.PropertyDescriptor
{
获取{return property;}
}
#端区
}
别开玩笑!我开始收集一个样本(我过去做过类似的事情),结果很快就失控了。