el2*_*ot2 7 c# data-binding textbox typeconverter winforms
我有一个自定义的c#类型(只是一个例子):
public class MyVector
{
public double X {get; set;}
public double Y {get; set;}
public double Z {get; set;}
//...
}
Run Code Online (Sandbox Code Playgroud)
我想将它数据绑定到TextBox.Text:
TextBox textBox;
public MyVector MyVectorProperty { get; set;}
//...
textBox.DataBindings.Add("Text", this, "MyVectorProperty");
Run Code Online (Sandbox Code Playgroud)
基本上我需要转换为自定义值类型的字符串.在文本框中,我想要"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);
}
}
Run Code Online (Sandbox Code Playgroud)
并将其与我的结构相关联:
[TypeConverter(typeof(MyVectorConverter))]
public class MyVector { //... }
Run Code Online (Sandbox Code Playgroud)
这似乎完成了一半的战斗.我可以看到MyVectorConverter
被召唤,但有些不对劲.它被调用以查看它是否知道如何转换为字符串,然后调用它来转换为字符串.但是,永远不会查询它是否可以转换FROM字符串,也不会实际进行转换.此外,在文本框中编辑后,立即替换旧值(另一个CanConvertTo和ConvertTo序列,恢复旧值).最终结果是文本框中新键入的条目在应用后立即恢复.
我觉得好像有一些简单的缺失.在那儿?整个项目/方法注定要失败吗?有没有其他人尝试这种疯狂?如何将自定义多部分类型双向绑定到基于字符串的控件?
解决方案:奇怪的是,所需要的只是在Binding对象上启用"格式化".(谢谢Jon Skeet):
textBox.DataBindings.Add("Text", this, "MyVectorProperty"); //FAILS
textBox.DataBindings.Add("Text", this, "MyVectorProperty", true); //WORKS!
Run Code Online (Sandbox Code Playgroud)
奇怪的是,我的MSDN提到的关于这个参数(formattingEnabled)的所有内容是:
"如果格式化显示的数据,则为true;否则为false"
它没有提到要求数据从控制中返回(在这些条件下).
Jon*_*eet 10
得到它了!
将该Binding.FormattingEnabled
属性设置为true.这似乎使一切顺利.您可以通过对ControlBindingsCollection.Add
方法的重载来执行此操作,该方法最后采用布尔参数.奇怪的是它以前的方式工作,但之前没有,但我的测试应用程序现在肯定有效......
(旧答案如下)
如果你有一个结构而不是一个类的事实在这里很重要,我会不会感到惊讶 - 以及你使用字段而不是属性的方式.
尝试使用自动实现属性的类:
public class MyClass
{
public int IntPart { get; set; }
public string StringPart { get; set; }
//...
}
Run Code Online (Sandbox Code Playgroud)
这可能不是问题的根源,但是使用带有公共字段的可变结构只是在寻找IMO的麻烦.
编辑:正如评论中所提到的,我现在已经开始运行了一个例子.正在使用正确的值引发Binding.Parse.现在找出为什么没有调用TypeConverter ...
编辑:我发现了一篇有用的文章,更详细地描述了绑定.似乎建议类型转换器仅用于将"转换"为另一种类型 - 因此您需要类型转换器string
才能知道如何转换为自定义类型.对我而言,这似乎很奇怪,但还有两个选择:
这些都没有完全相同的吸引力,但它们可能足以为您提供解决方案.我确信有一种方法可以使用TypeConverters来实现这一点,但是如果我现在可以看到它,我会感到很震惊.