C# 如何将自定义类型数据绑定到TextBox.Text?
我有一个自定义c#类型,如(仅举一个例子): 我想让它数据绑定到文本框。文本:C# 如何将自定义类型数据绑定到TextBox.Text?,c#,winforms,data-binding,textbox,typeconverter,C#,Winforms,Data Binding,Textbox,Typeconverter,我有一个自定义c#类型,如(仅举一个例子): 我想让它数据绑定到文本框。文本: TextBox textBox; public MyVector MyVectorProperty { get; set;} //... textBox.DataBindings.Add("Text", this, "MyVectorProperty"); 本质上,我需要为我的自定义值类型在字符串之间进行转换。在文本框中,我需要类似“x,y,z”的内容,可以对其进行编辑以更新向量类型。我假设可以通过添加TypeCo
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
被调用到,但有点不对劲。调用它是为了查看它是否知道如何转换为字符串,然后调用它来转换为字符串。但是,永远不会查询它是否可以从字符串转换,也不会实际执行转换。此外,在文本框中进行编辑后,旧值立即被替换(另一个CanConvertTo和ConvertTo序列,恢复旧值)。最终结果是,文本框中新键入的条目在应用后立即恢复
我觉得好像只是缺少了一些简单的东西。有?整个项目/方法注定要失败吗?还有其他人尝试过这种疯狂吗?如何将自定义多部分类型双向绑定到基于字符串的控件
解决方案:奇怪的是,所需要的只是在绑定对象上启用“格式化”。(谢谢,Jon Skeet):
奇怪的是,我的MSDN只提到了这个参数(formattingEnabled):
true以格式化显示的数据;否则为false
它没有提到需要从控件返回数据(在这些条件下)。明白了强> 将属性设置为true。这似乎能让一切顺利。 您可以通过方法的重载来实现这一点,该方法在末尾接受一个布尔参数。 奇怪的是,它以前是以一种方式工作的,而不是以另一种方式,但我的测试应用程序现在肯定可以工作了 (旧答案如下) 如果您使用的是结构而不是类这一事实在这里很重要,以及您使用字段而不是属性的方式,我一点也不会感到惊讶 尝试使用自动实现的属性替换类:
public class MyClass
{
public int IntPart { get; set; }
public string StringPart { get; set; }
//...
}
这可能不是问题的根源,但在IMO中,使用带有公共字段的可变结构只是自找麻烦
编辑:正如评论中提到的,我现在已经有了一个例子并正在运行。正在使用正确的值引发Binding.Parse。现在要了解为什么没有调用TypeConverter
编辑:我发现了一个更详细地描述绑定的方法。这似乎表明类型转换器仅用于将“转换为”另一种类型-因此您需要string
的类型转换器来了解如何转换为自定义类型。诚然,这对我来说似乎很奇怪,但还有两种选择:
- 使用绑定的格式和解析事件进行转换
- 使类型实现IConvertible
这两种方法的吸引力都不尽相同,但它们可能足以解决您的问题。我确信有一种方法可以使用类型转换器来实现这一点,但如果我现在能看到它,我会大吃一惊。感谢您的反馈,我已经澄清了这个示例,并使问题更一般化了。我的示例是一个简单的结构,但我已将其更改为引用类型以演示更广泛的问题。将其设置为带有公共字段的结构肯定不会增加简单性:)这是在Windows窗体、WPF、ASP.NET还是什么中?取决于您对“简单性”的启发(代码的简单性、示例的简单性、在interop中使用数据类型的简单性……等等),但我离题了。我试图在windows窗体中使用该解决方案,但我认为问题与一般的数据绑定相关。可变结构在任何上下文中都很少意味着简单。无论如何,我已经重现了这个问题,但我也无法使其起作用。正如你所说,绑定似乎只在显示端。仍然在寻找。事实上,这就是谢谢你的帮助,我很感激。
textBox.DataBindings.Add("Text", this, "MyVectorProperty"); //FAILS
textBox.DataBindings.Add("Text", this, "MyVectorProperty", true); //WORKS!
public class MyClass
{
public int IntPart { get; set; }
public string StringPart { get; set; }
//...
}