在 PropertiesGrid 中将自定义对象列表显示为下拉列表
我想要一个对象,假设这个对象:
public class BenchmarkList
{
public string ListName { get; set; }
public IList<Benchmark> Benchmarks { get; set; }
}
并让该对象将其 ListName 显示为 PropertiesGrid 的“名称”部分(“基准”会很好),对于 PropertyGrid 的“值”部分,要具有IList<> 的下拉列表基准:
这是基准对象,
public class Benchmark
{
public int ID {get; set;}
public string Name { get; set; }
public Type Type { get; set; }
}
我希望下拉列表显示基准的名称属性,以便用户可以看到。这是一个直观的示例:
因此,本质上,我试图将 Benchmark 对象的集合放入下拉列表,这些对象应将其 Name 属性显示为下拉列表中的值。
我读过有关使用 PropertiesGrid 的其他文章,包括 THIS 和 < a href="http://www.codeproject.com/KB/miscctrl/bending_property.aspx" rel="noreferrer">这个,但它们比我想做的更复杂。
我通常从事服务器端的工作,并且不通过 WebForms 或 WinForms 处理 UI,所以这个 PropertiesGrid 确实让我很开心......
我确实知道我的解决方案在于实现“ICustomTypeDescriptor”,这将允许我告诉 PropertiesGrid 它应该显示什么值,而不管我想要绑定到下拉列表中的对象的属性如何,但我只是不确定如何或在哪里实现它。
任何指示/帮助将不胜感激。
谢谢, 迈克
更新:
好的,所以我稍微改变一下细节。我之前对我认为应该涉及的对象太过分了,所以这是我的新方法。
我有一个名为 Analytic 的对象。这是应该绑定到 PropertiesGrid 的对象。现在,如果我公开一个枚举类型的属性,PropertiesGrid 将为我处理下拉列表,这非常好。如果我公开一个自定义类型集合的属性,PropertiesGrid 就不太好...
这是 Analytic 的代码,我想要绑定到 PropertiesGrid 的对象:
public class Analytic
{
public enum Period { Daily, Monthly, Quarterly, Yearly };
public Analytic()
{
this.Benchmark = new List<IBenchmark>();
}
public List<IBenchmark> Benchmark { get; set; }
public Period Periods { get; set; }
public void AddBenchmark(IBenchmark benchmark)
{
if (!this.Benchmark.Contains(benchmark))
{
this.Benchmark.Add(benchmark);
}
}
}
这是一个简短的示例,其中两个对象实现了IBenchmark 接口:
public class Vehicle : IBenchmark
{
public Vehicle()
{
this.ID = "00000000-0000-0000-0000-000000000000";
this.Type = this.GetType();
this.Name = "Vehicle Name";
}
public string ID {get;set;}
public Type Type {get;set;}
public string Name {get;set;}
}
public class PrimaryBenchmark : IBenchmark
{
public PrimaryBenchmark()
{
this.ID = "PrimaryBenchmark";
this.Type = this.GetType();
this.Name = "Primary Benchmark";
}
public string ID {get;set;}
public Type Type {get;set;}
public string Name {get;set;}
}
这两个对象将被添加到 WinForms 代码中的分析对象的基准列表集合中:
private void Form1_Load(object sender, EventArgs e)
{
Analytic analytic = new Analytic();
analytic.AddBenchmark(new PrimaryBenchmark());
analytic.AddBenchmark(new Vehicle());
propertyGrid1.SelectedObject = analytic;
}
这是 PropertiesGrid 中输出的屏幕截图。请注意,作为枚举公开的属性会获得一个很好的下拉列表,但无需任何工作,但作为 List 公开的属性会获得 (Collection) 值。当您单击(集合)时,您将获得集合编辑器,然后可以看到每个对象及其各自的属性:
这不是我要找的。就像我在这篇文章中的第一个屏幕截图中一样,我试图将 List 的属性 Benchmark 集合渲染为下拉列表,该下拉列表将对象的名称属性显示为可显示内容的文本...
谢谢
I want to take an object, let's say this object:
public class BenchmarkList
{
public string ListName { get; set; }
public IList<Benchmark> Benchmarks { get; set; }
}
and have that object display its ListName as the "name" part of the PropertiesGrid ("Benchmark" would be good), and for the "value" part of the PropertyGrid, to have a drop-down list of the IList<> of Benchmarks:
here is the Benchmark object
public class Benchmark
{
public int ID {get; set;}
public string Name { get; set; }
public Type Type { get; set; }
}
I would want the drop-down to show the Name property of the Benchmark for what the users can see. Here is a visual example:
So, essentially, I'm trying to get a collection of Benchmark objects into a drop-down list, and those objects should show their Name property as the value in the drop-down.
I've read other articles on using the PropertiesGrid, including THIS and THIS, but they are more complex than what I'm trying to do.
I usually work on server-side stuff, and don't deal with UI via WebForms or WinForms, so this PropertiesGrid is really taking me for a ride...
I do know my solution lies in implementing "ICustomTypeDescriptor", which will allow me to tell the PropertiesGrid what values it should be displaying regardless of the properties of the object to which I want to bind into the drop-down list, but I'm just not sure how or where to implement it.
Any pointers/help would be much appreciated.
Thanks,
Mike
UPDATE:
Okay, so I'm changing the details around a little. I was going overboard before with the objects I thought should be involved, so here is my new approach.
I have an object called Analytic. This is the object that should be bound to the PropertiesGrid. Now, if I expose a property that is of an enum type, PropertiesGrid will take care of the drop-down list for me, which is very nice of it. If I expose a property that is a collection of a custom type, PropertiesGrid is not so nice...
Here is the code for Analytic, the object I want to bind to the PropertiesGrid:
public class Analytic
{
public enum Period { Daily, Monthly, Quarterly, Yearly };
public Analytic()
{
this.Benchmark = new List<IBenchmark>();
}
public List<IBenchmark> Benchmark { get; set; }
public Period Periods { get; set; }
public void AddBenchmark(IBenchmark benchmark)
{
if (!this.Benchmark.Contains(benchmark))
{
this.Benchmark.Add(benchmark);
}
}
}
Here is a short example of two objects that implement the IBenchmark interface:
public class Vehicle : IBenchmark
{
public Vehicle()
{
this.ID = "00000000-0000-0000-0000-000000000000";
this.Type = this.GetType();
this.Name = "Vehicle Name";
}
public string ID {get;set;}
public Type Type {get;set;}
public string Name {get;set;}
}
public class PrimaryBenchmark : IBenchmark
{
public PrimaryBenchmark()
{
this.ID = "PrimaryBenchmark";
this.Type = this.GetType();
this.Name = "Primary Benchmark";
}
public string ID {get;set;}
public Type Type {get;set;}
public string Name {get;set;}
}
These two objects will be added to the Analytic object's Benchmark List collection in the WinForms code:
private void Form1_Load(object sender, EventArgs e)
{
Analytic analytic = new Analytic();
analytic.AddBenchmark(new PrimaryBenchmark());
analytic.AddBenchmark(new Vehicle());
propertyGrid1.SelectedObject = analytic;
}
Here is a screen-grab of the output in the PropertiesGrid. Note that the property exposed as an enum gets a nice drop-down list with no work, but the property exposed as an of List on gets a value of (Collection). When you click on (Collection), you get the Collection editor and then can see each object, and their respective properties:
This is not what I'm looking for. Like in my first screen grab in this post, I'm trying to render the property Benchmark collection of List as a drop-down list that shows the object's name property as the text of what can be displayed...
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通常,属性网格中的下拉列表用于设置给定列表中的属性值。这意味着您最好拥有一个类似 IBenchmark 类型的“Benchmark”的属性以及其他地方可能的 IBenchmark 列表。我冒昧地更改了您的分析类,如下所示:
您现在需要的不是 ICustomTypeDescriptor,而是
TypeConverter
和UITypeEditor
。您需要使用 UITypeEditor 来装饰 Benchmark 属性(如上所述),并使用 TypeConverter 来装饰 IBenchmark 界面,如下所示:这是一个示例 TypeConverter 实现:
这是一个示例 UITypeEditor 实现:
In general, a drop down list in a property grid is used for setting the value of a property, from a given list. Here that means you should better have a property like "Benchmark" of type IBenchmark and a possible list of IBenchmark somewhere else. I have taken the liberty of changing your Analytic class like this:
What you need now is not an ICustomTypeDescriptor, but instead a
TypeConverter
an anUITypeEditor
. You need to decorate the Benchmark property with the UITypeEditor (as above) and the IBenchmark interface with the TypeConverter like this:Here is a sample TypeConverter implementation:
And here is a sample UITypeEditor implementation: