属性��格控件和下拉列表

8

我希望创建一个下拉列表作为属性的编辑器;如果下拉列表中只有字符串作为选项,使用StringConverter可以很好地工作。然而,当我尝试使用对象列表而不是字符串时,它就无法正常工作(注意,它对于普通的组合框可以正常工作!) 这是我的代码:

    public static List<Bar> barlist;
    public Form1()
    {
        InitializeComponent();
        barlist = new List<Bar>();
        for (int i = 1; i < 10; i++)
        {
            Bar bar = new Bar();
            bar.barvalue = "BarObject " + i;
            barlist.Add(bar);
            comboBox1.Items.Add(bar);
        }
        Foo foo = new Foo();
        foo.bar = new Bar();
        propertyGrid1.SelectedObject = foo;
    }

    public class Foo
    {
        Bar mybar;

        [TypeConverter(typeof(BarConverter))]
        public Bar bar
        {
            get { return mybar; }
            set { mybar = value; }
        }
    }

    public class Bar
    {
        public String barvalue;
        public override String ToString()
        {
            return barvalue;
        }
    }


    class BarConverter : TypeConverter
    {
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            return new StandardValuesCollection(barlist);
        }
    }
等嵌入式结果如下:

在这里输入图像描述

点击一个条目会给我这个:

在这里输入图像描述

(对于德语文本我很抱歉,我不确定是否可以更改,我的 VS 是英文的,但我的操作系统不是,错误消息是

  Invalid property value.

  The object of type "System.String" cannot be converted to type 
  "XMLTest.Form1+Bar".

我相信我可以通过定义反向转换工具来解决这个问题,将字符串转换回Bar对象。为了使其正常工作,这将需要使用不同的键。有没有更好的方法?为什么嵌入到propertyGrid控件中的comboBox使用字符串(普通的comboBox在处理此问题时没有任何问题)

此外,我能否通过编程方式更改中间分隔符的位置?我还没有找到这个选项。

谢谢。


这只是一些条形图对象的列表,没有什么特别的。我也应该将其包含在我的代码中吗? - CBenni
1个回答

6

我已经在你的转换类中添加了CanConvertFromConvertFrom方法:

class BarConverter : TypeConverter
{
  public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
  {
    return true;
  }

  public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
  {
    return new StandardValuesCollection(barlist);
  }

  public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
  {
    if (sourceType == typeof(string))
    {
      return true;
    }
    return base.CanConvertFrom(context, sourceType);
  }

  public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
  {
    if (value is string)
    {
      foreach (Bar b in barlist)
      {
        if (b.barvalue == (string)value)
        {
          return b;
        }
      }
    }
    return base.ConvertFrom(context, culture, value);
  }
}

1
只要barlist中没有重复的名称,这个方法就可以正常工作(但是这并不被禁止,因为两个bar对象可能是不同的,但具有相同的名称)。对于你的努力给予+1。你有什么想法可以让它即使有重复也能正常工作吗? - CBenni
@CBenni 我只是在尝试让你的代码没有错误地运行。你的“string”必须是唯一的,因为这是你想要转换的内容。 - LarsTech
由于这是唯一的答案,它可以工作(大多数情况下),并且很可能永远不会有其他答案,因此我将继续接受它。 - CBenni
因为重复名称的缺点被踩了。 - stigzler
@stigzler 这个问题不是关于重复的。 - LarsTech
不是明确表述,但通过代码结构基本能推断出来。2+2=4。 - stigzler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接