我有一个自定义的 c# 类型,比如(只是一个例子):
public class MyVector
{
public double X {get; set;}
public double Y {get; set;}
public double Z {get; set;}
//...
}
我希望它数据绑定到 TextBox.Text:
TextBox textBox;
public MyVector MyVectorProperty { get; set;}
//...
textBox.DataBindings.Add("Text", this, "MyVectorProperty");
本质上,我需要为我的自定义值类型转换为字符串和从字符串转换。在文本框中,我想要“x, y, z”之类的内容,可以对其进行编辑以更新矢量类型。我假设我可以通过添加TypeConverter
派生类来做到这一点:
public class MyVectorConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context,
Type sourceType)
{
if (sourceType == typeof(string))
return true;
//...
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context,
Type destinationType)
{
if (destinationType == typeof(string))
return true;
//...
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture,
object value)
{
if (value is string)
{
MyVector MyVector;
//Parse MyVector from value
return MyVector;
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture,
object value,
Type destinationType)
{
if (destinationType == typeof(string))
{
string s;
//serialize value to string s
return s;
}
//...
return base.ConvertTo(context, culture, value, destinationType);
}
}
并将其与我的结构相关联:
[TypeConverter(typeof(MyVectorConverter))]
public class MyVector { //... }
这似乎完成了一半的战斗。我可以看到MyVectorConverter
被召唤,但有些不对劲。调用它看它是否知道如何转换为字符串,然后调用它转换为字符串。但是,永远不会查询它是否可以转换 FROM 字符串,也不会实际进行转换。此外,在文本框中进行编辑后,旧值立即被替换(另一个 CanConvertTo 和 ConvertTo 序列,恢复旧值)。最终结果是文本框中新键入的条目在应用后立即恢复。
我觉得好像只是缺少一些简单的东西。有没有?这整个项目/方法注定要失败吗?还有其他人尝试这种疯狂吗?如何将自定义的多部分类型双向绑定到基于字符串的控件?
解决方案:奇怪的是,只需要在 Binding 对象上启用“格式化”即可。(谢谢,乔恩斯基特):
textBox.DataBindings.Add("Text", this, "MyVectorProperty"); //FAILS
textBox.DataBindings.Add("Text", this, "MyVectorProperty", true); //WORKS!
奇怪的是,我的 MSDN 提到的关于这个参数(formattingEnabled)的所有内容都是:
"true 以格式化显示的数据;否则为 false"
它没有提到它是从控件返回数据的要求(在这些条件下)。