I have a property on my World
class that looks like this:
public Vec2 Gravity
{
get {
Console.WriteLine("Getting gravity!");
return GetGravity();
}
set {
Console.WriteLine("Setting gravity!");
SetGravity(value);
}
}
The "Getting gravity!" string is displayed as expected, when the PropertyGrid
tries to read the value, but when I try to change the gravity vector and press enter, nothing happens. Why not?
My Vec2
class has properties:
public float X
{
get
{
return x;
}
set
{
x = value;
}
}
public float Y
{
get
{
return y;
}
set
{
y = value;
}
}
Which are visible on the grid, thanks to:
public class Vec2Converter : ExpandableObjectConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, System.Type destinationType)
{
if (destinationType == typeof(Vec2)) return true;
else return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType)
{
if (destinationType == typeof(string) && value is Vec2)
{
Vec2 vec = (Vec2)value;
return string.Format("{0}, {1}", vec.X, vec.Y);
}
else return base.ConvertTo(context, culture, value, destinationType);
}
}
I just added these two methods to the Vec2Converter
and now it works:
public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
{
if (sourceType == typeof(string)) return true;
else return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
try
{
string strVal = value as string;
var parts = strVal.Split(',');
float x = float.Parse(parts[0]);
float y = float.Parse(parts[1]);
return new Vec2(x, y);
}
catch
{
throw new ArgumentException("Can not convert '" + (string)value + "'to type Vec2");
}
}
else return base.ConvertFrom(context, culture, value);
}
It works both by changing the string representation, and the individual properties. Why does thix fix it for the case with individual properties??
I think the answer is that Vec2
is a struct, so when World
returns the Gravity
vector, it passes it by value, and then the copy is changed, rather than the actual Gravity
vector.
The solution, I think is either to keep the CanConvertFrom
and ConvertFrom
methods in place. I'm assuming those make it work because they modify the string representation of the gravity vector, and then that in turn updates the actual gravity vector. That, or making Vec2
a class ought to work, but I can't really test that now because my app is very dependent on it being a struct.