将自定义对象列表显示为绑定到 PropertyGrid 中 .SelectedObject 的对象的属性

发布于 2024-10-20 02:03:03 字数 2180 浏览 3 评论 0原文

我将再次破解这个问题,因为我之前发布的原始问题格式不正确,并且我没有首先进行足够的研究来提出有关 PropertyGrid 的清晰、简洁的问题。希望这会更好。

我想将此对象绑定到属性网格:

public class Analytic
{
    public enum Period { Daily, Monthly, Quarterly, Yearly};
    public Analytic()
    {
        this.Benchmark = new List<Benchmark>();
    }
    public List<Benchmark> Benchmark { get; set; }
    public Period Periods { get; set; }
    public void AddBenchmark(Benchmark benchmark)
    {
        if (!this.Benchmark.Contains(benchmark))
        {
            this.Benchmark.Add(benchmark);
        }
    }
}

该对象公开两种类型的属性,一是枚举类型,二是 Benchmark 类型的自定义类型。我希望这两种类型都显示为下拉列表。我知道 PropertyGrid 会自动为基于枚举的属性创建一个下拉列表。我的问题是尝试将基准列表显示为下拉列表。我想要的是让 Benchmark 的 Name 属性成为下拉列表中显示的文本。以下是 Benchmark 的代码:

public class Benchmark
{
    public Benchmark(string id, string name)
    {
        this.ID = id;
        this.Name = name;
    }
    public string ID { get; set; }
    public string Name { get; set; }
}

尝试将对象绑定到 PropertyGrid,使用此调用代码:

Analytic analytic = new Analytic();
analytic.AddBenchmark(new Benchmark("1", "BM1"));
analytic.AddBenchmark(new Benchmark("2", "BM2"));
propertyGrid1.SelectedObject = analytic;

会产生以下输出: 在此处输入图像描述

在上面的屏幕截图中,您可以看到基准对象列表正在呈现为“(集合)”。我希望每个基准的名称与 periods 枚举的显示方式相同。输出将是这样的:

在此处输入图像描述

最大的问题是,如何做到这一点?

我见过几个“helper”类继承自“System.ComponentModel.StringConverter”的示例,但这通常假设集合本身是一个数组或字符串集合。 这里有使用 StringConverter 的好例子(构建一个下拉列表州)和 HERE(构建规则的下拉列表)。

在我的示例中,我的集合是自定义类型 Benchmark 的集合,但我仍然不知道:

  1. 如果我可以使用任何基类/接口,它将帮助我完成 Benchmark 需要做的事情,类似于上述两个链接对字符串类型有何帮助。
  2. 如果网上有一个很好的、简单的例子来说明我需要完成什么,

我会发现在绑定到 PropertyGrid 的对象的某些公开属性上显示非基本类型下拉列表这样一项微不足道的任务是如此疯狂痛苦。

再次强调,任何帮助或任何正确方向的指示将不胜感激。

谢谢, 麦克风

I'm going to take another crack at this question b/c the original question I posted earlier was poorly formed, and I did not do enough research first to present a clear, concise question regarding the PropertyGrid. Hopefully, this will be better.

I want to bind this object to the Property Grid:

public class Analytic
{
    public enum Period { Daily, Monthly, Quarterly, Yearly};
    public Analytic()
    {
        this.Benchmark = new List<Benchmark>();
    }
    public List<Benchmark> Benchmark { get; set; }
    public Period Periods { get; set; }
    public void AddBenchmark(Benchmark benchmark)
    {
        if (!this.Benchmark.Contains(benchmark))
        {
            this.Benchmark.Add(benchmark);
        }
    }
}

The object exposes two types of properties, one, an enum type, and two, a custom type of type Benchmark. I want both types to be displayed as drop-down lists. I know that PropertyGrid automatically creates a drop-down list for the enum-based property. My problem is trying to get the list of Benchmarks to display as a drop-down list. What I would like is to have the Name property of Benchmark to be the text that appears in the drop-down list. Here is the code for Benchmark:

public class Benchmark
{
    public Benchmark(string id, string name)
    {
        this.ID = id;
        this.Name = name;
    }
    public string ID { get; set; }
    public string Name { get; set; }
}

Trying to bind the object to a PropertyGrid, using this calling code:

Analytic analytic = new Analytic();
analytic.AddBenchmark(new Benchmark("1", "BM1"));
analytic.AddBenchmark(new Benchmark("2", "BM2"));
propertyGrid1.SelectedObject = analytic;

results in this output:
enter image description here

in the screen-grab above, you can see the list of Benchmark objects is being rendered as "(Collection)". I want the names of each Benchmark to appear just how the Periods enum appears. The output would be something like this:

enter image description here

The big question is, how to do this?

I've seen a couple examples of "helper" classes inherit from "System.ComponentModel.StringConverter", but this usually assumes the collection itself is an array or a collection of Strings. There are good examples of using StringConverter HERE (build a drop-down list of States) and HERE (builds a drop-down list of Rules).

In my example, my collection is a collection of a custom type, Benchmark, and I still don't know:

  1. What, if any base classes/interfaces I can use that will help me do what I need to do for Benchmark, similar to how the above two links helped for String types.
  2. If there is one good, simple example anywhere online of what I need to accomplish

I find it insane that such a trivial task of showing a drop-down list of non-primitive types on some exposed properties of an object bound to the PropertyGrid is so painful.

Again, any help, or any pointers in the right direction would be much appreciated.

Thanks,
Mike

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

故事↓在人 2024-10-27 02:03:03

我知道这已经很旧了,但也许对其他人有帮助。

在我看来,您可以将这个问题分解为两部分:首先,您想要在属性网格中显示自定义字符串列表。第二,您希望根据自定义字符串列表中的一个选择在自定义对象中设置属性。以这种方式分解它,它变得非常容易。对于第一部分,您可以使用 TypeConverter。

[TypeConverter(typeof(MyCustomSelect))]
public String Flavor { get; set; }

MyCustomSelect 是一种仅提供可供选择的字符串列表的类型。例如:

public class MyCustomSelect : TypeConverter
{
    public override bool
    GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true; // display drop
    }
    public override bool
    GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true; // drop-down vs combo
    }
    public override StandardValuesCollection
    GetStandardValues(ITypeDescriptorContext context)
    {
        // can look at context to build list, if necessary
        return new StandardValuesCollection(new string[] { "abc", "def", "ghi" });
    }
}

好的,现在,这是一个字符串属性。这不是您想要的自定义类型。当为此字符串选择新值时,如何在对象上设置属性?只需实现一个设置器即可。

    [TypeConverter(typeof(MyCustomSelect))]
    public String Flavor
    {
        get { return _flavor; }
        set 
        {
            _flavor = value;
            OtherProperty = OtherCustomObject.Create(_flavor);
        }
    }
    private string _flavor;

    [Browsable(false)]
    public OtherCustomObject OtherProperty { get; set; }

工厂方法 OtherCustomObject.Create() 留给您实现。


现在,如果您确实想设置其他自定义对象的列表,则需要实现一个集合编辑器,并在其中显示下拉列表。

I know this is old, but maybe it will help someone else.

Seems to me you can decompose this problem into 2 parts: first, you want to display a custom list of strings in the propertygrid. 2nd, you want to set a property in the custom object, based on one selection from that custom list of strings. Breaking it down this way, it gets pretty easy. For the first part, you can use a TypeConverter.

[TypeConverter(typeof(MyCustomSelect))]
public String Flavor { get; set; }

The MyCustomSelect is a type that simply provides a list of strings to select from. For example:

public class MyCustomSelect : TypeConverter
{
    public override bool
    GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true; // display drop
    }
    public override bool
    GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true; // drop-down vs combo
    }
    public override StandardValuesCollection
    GetStandardValues(ITypeDescriptorContext context)
    {
        // can look at context to build list, if necessary
        return new StandardValuesCollection(new string[] { "abc", "def", "ghi" });
    }
}

Ok, now, this is a string property. It's not that custom type you wanted. How do you set a property on your object, when a new value is selected for this string? Just implement a setter.

    [TypeConverter(typeof(MyCustomSelect))]
    public String Flavor
    {
        get { return _flavor; }
        set 
        {
            _flavor = value;
            OtherProperty = OtherCustomObject.Create(_flavor);
        }
    }
    private string _flavor;

    [Browsable(false)]
    public OtherCustomObject OtherProperty { get; set; }

The factory method OtherCustomObject.Create() is left for you to implement.


Now, if you really want to set a List of other custom objects, you need to implement a collection editor, and within THAT, you can display the dropdown.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文