2009-01-22 77 views
7

我有一个自定义的C#类型一样(只是一个例子):如何将一个自定义类型绑定到TextBox.Text?

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序列,恢复旧值)。最终结果是文本框中新输入的条目在应用后立即恢复。

我觉得好像只有一些简单的失踪。在那儿?这整个项目/方法注定要失败吗?有没有人试图这样疯狂?如何双向绑定自定义的多部分类型到基于字符串的控件?

解决方案:奇怪的是,所有需要的是在绑定对象上启用“格式化”。 (感谢,乔恩斯基特):

textBox.DataBindings.Add("Text", this, "MyVectorProperty"); //FAILS 
textBox.DataBindings.Add("Text", this, "MyVectorProperty", true); //WORKS! 

奇怪的是,所有我MSDN提到有关此参数(formattingEnabled)是:

“真格式化显示的数据;否则为false”

它没有提及它是数据从控件返回(在这些条件下)的要求。

回答

10

Got it!

Binding.FormattingEnabled属性设置为true。这似乎使这一切工作。 您可以通过ControlBindingsCollection.Add方法的超负荷做到这一点,该方法最后采用布尔参数。 这是奇怪的是,它的工作的一种方式,但不是之前其他的,但肯定我的测试应用程序现在工作...

(以下旧答案)

,我也不会感到惊讶,如果事实,你'有一个结构,而不是一个类在这里很重要 - 以及你使用字段而不是属性的方式。

尝试使用autoimplemented属性的类来代替:

public class MyClass 
{ 
    public int IntPart { get; set; } 
    public string StringPart { get; set; } 
    //... 
} 

这可能不是问题的根源,但使用可变结构具有公共字段是自找麻烦海事组织。

编辑:正如在评论中提到的,我现在已经有一个例子启动并运行。 Binding.Parse会以正确的值提升。现在找出为什么TypeConverter没有被调用...

编辑:我找到了一个useful article,它描述了更详细的绑定。似乎表明类型转换器仅用于将“转换”为另一种类型 - 因此您需要使用string的类型转换器来知道如何转换为自定义类型。这似乎很奇怪,我,无可否认,但也有其他两个选项:

  • 使用格式化和分析结合来进行转换
  • 让类型实现IConvertible

既不事件这些吸引力的方式完全相同,但他们可能已足够为您解决。我确信有一种方法可以使用TypeConverters来实现这个功能,但如果我现在可以看到它的话,我会受到打击。

+0

感谢您的反馈,我澄清了这个例子,并提出了更通用的问题。我的例子是一个简单的结构,但我已经将它改为参考类型来演示更广泛的问题。 – el2iot2 2009-01-22 18:05:57

相关问题