Reputation: 109
I've been playing around with PropertyGrids, linking them to classes and am trying to figure out how (if possible) I can display a class, with sub classes inside the PropertyGrid in a flat structure (as if they were all in one class)
I have a couple of classes, Foo and Bar as per below:
[Serializable()]
public class Foo
{
private string m_Code;
private Bar m_Bar = new Bar();
[DisplayName("Code")]
[Description("The Code of Foo")]
public string Code
{
get { return m_Code; }
set { m_Code = value; }
}
public Bar Bar
{
get { return m_Bar; }
set { m_Bar = value; }
}
}
and
[TypeConverter(typeof(ExpandableObjectConverter))]
[Serializable()]
public class Bar
{
private string m_Name;
[DisplayName("Name")]
[Description("The Name of Bar")]
public string Name
{
get { return m_Name; }
set { m_Name = value; }
}
}
What I am trying to understand / figure out is if I can modify the way that the data is then displayed in the PropertyGrid.
Specifically I would like to display both Foo.Code and Bar.Name in a flat / organised structure, the same way as if they were both in the same class.
If I use don't use a TypeConverter, or attempt to use [TypeConverter(typeof(Bar))] then I see my Bar class in the PropertyGrid, but just a single line, and can't edit the Name property.
If I use [TypeConverter(typeof(ExpandableObjectConverter))] as above, then I can see an expand arrow for Bar, and underneath that the property for Name... all seems good.
However, I both have to expand the group, and it displays the class name to the right hand side. Obviously I can call PropertyGrid.ExpandAllGridItems(); as needed, but it is also ugly.
If I use [Category("Bar")], then it is included, and organised in the flat structure as desired, but still with the above problems (expand level and class name)
Am I missing something obvious here? Or is it a case that I need to implement some kind of custom type converter? And if so, how to go about doing that?
Edit:
To clarify further, when I use nested class, it is displayed like below, so shows the class name on the right, and expand arrow.
I would like to have the nested classes like as shown below / as if Foo was just one class with Code and Name.
Edit2:
Trying to implement a Type convertor, and that seems to be displaying ok, but now I can't edit the value at all (i.e Bar.Name )
[TypeConverter(typeof(BarConverter))]
[Serializable()]
public class Bar
{
private string m_Name;
[DisplayName("Name")]
[Description("The Name of Bar")]
public string Name
{
get { return m_Name; }
set { m_Name = value; }
}
}
public class BarConverter : TypeConverter
{
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
Bar _Bar = (Bar)value;
return _Bar.Name;
}
}
Edit 3:
Type converter seems to work for getting the values, but now cannot edit the Bar.Name values, it is just greyed out:
Current TypeConverter
public class BarConverter : TypeConverter
{
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
Bar _Bar = (Bar)value;
return _Bar.Name;
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
return base.ConvertFrom(context, culture, value);
}
}
Edit #4
I think this is going in the too hard basket. Too much time going round in circles :(
Upvotes: 4
Views: 7668
Reputation: 454
I've solved a similar problem by just overriding the class's ToString() method. Solution found here.
[Serializable()]
public class Bar
{
private string m_Name;
[DisplayName("Name")]
[Description("The Name of Bar")]
public string Name
{
get { return m_Name; }
}
public override string ToString()
{
return "Name you want to display";
}
}
Upvotes: 0
Reputation: 866
I think you should override ExpandableObjectConverter
instead of TypeConverter
.
public class BarConverter : ExpandableObjectConverter
{
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
Bar _Bar = (Bar) value;
return _Bar.Name;
}
}
Upvotes: 0