如何将自定义类型的数据绑定到TextBox.Text? [英] How does one databind a custom type to TextBox.Text?

查看:813
本文介绍了如何将自定义类型的数据绑定到TextBox.Text?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义的c#类型(只是一个例子):

I have a custom c# type like (just an example):

public class MyVector
{ 
   public double X {get; set;} 
   public double Y {get; set;} 
   public double Z {get; set;} 
   //...
}

而且我想要将数据绑定到TextBox.Text:

And I want it to databind to TextBox.Text:

TextBox textBox;
public MyVector MyVectorProperty { get; set;}
//...
textBox.DataBindings.Add("Text", this, "MyVectorProperty");

本质上,我需要从字符串转换到我的自定义值类型。在文本框中,我想要一些类似x,y,z的东西,可以编辑以更新矢量类型。我假设我可以通过添加一个 TypeConverter 派生类来实现:

Essentially I need conversion to and from a string for my custom value type. In the text box, I want something like "x, y, z" that can be edited to update the vector type. I assumed that I could do so by adding a TypeConverter derived class:

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);
    }
}

并将其与我的结构相关联:

and associating it with my struct:

[TypeConverter(typeof(MyVectorConverter))]
public class MyVector { //... }

这似乎完成了一半的战斗。我可以看到 MyVectorConverter 被调用,但有些是不幸。调用它是否知道如何转换为字符串,然后调用它来转换为字符串。但是,从来没有查询过它是否可以转换FROM字符串,也不能实际进行转换。此外,在文本框中编辑之后,将立即替换旧值(另一个CanConvertTo和ConvertTo序列,恢复旧值)。最终的结果是应用后,文本框中新键入的条目将立即被还原。

This appears to complete half of the battle. I can see MyVectorConverter getting called into, but something is amiss. It is called to see if it knows how to convert to string, then it is called to convert to string. However, it is never queried to see if it can convert FROM string nor to actually do the conversion. Furthermore, right after an edit in the textbox, the old value is immediately replaced (another CanConvertTo and ConvertTo sequence, restoring the old value). The end result is that the newly typed entry in the text box is reverted immediately after it is applied.

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

I feel as if there is just something simple missing. Is there? Is this entire project/approach doomed to failure? Does anyone else attempt such madness? How does one bi-directionally bind a custom, multipart type to a string-based control?

解决方案:奇怪的是,所需要的只是以便在绑定对象上启用格式化。 (感谢Jon Skeet):

Solution: Bizarrely, all that is needed is for the "formatting" to be enabled on the Binding object. (thanks, Jon Skeet):

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

奇怪的是,我的MSDN提到这个参数(formattingEnabled)是:

Oddly, all that my MSDN mentions about this parameter (formattingEnabled) is:


true格式化显示的数据;否则为false

"true to format the displayed data; otherwise, false"

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

It mentions nothing about it being a requirement for the data to come back from the control (under these conditions).

推荐答案

得到它!

设置 Binding.FormattingEnabled 属性为true。这似乎使它一切正常。
您可以对 ControlBindingsCollection.Add 方法,在最后采用一个布尔参数。
这是奇怪的,它以一种方式工作但不是另一种,但是我的测试应用程序现在可以工作...

Set the Binding.FormattingEnabled property to true. This seems to make it all work. You can do this with an overload to the ControlBindingsCollection.Add method which takes a Boolean parameter at the end. It's odd that it worked one way but not the other before, but certainly my test app now works...

(以下回答)

我不会惊讶,如果你有一个结构而不是一个类在这里很重要 - 以及你使用字段而不是属性。

I wouldn't be at all surprised if the fact that you're got a struct instead of a class was important here - as well as the way you're using fields instead of properties.

使用自动实现的属性尝试使用一个类:

Try with a class using autoimplemented properties instead:

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

这可能不是根本的问题,但使用一个可变结构与公共领域只是要求麻烦IMO。

This may well not be the root of the problem, but using a mutable struct with public fields is just asking for trouble IMO.

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

As mentioned in the comments, I've now got an example up and running. The Binding.Parse is being raised with the right value. Now to find out why the TypeConverter isn't being called...

编辑:我找到一个有用的文章,其中更详细地描述了绑定。似乎建议类型转换器仅用于将转换为另一种类型 - 所以您需要 string 的类型转换器来了解如何转换为自定义类型。对我来说这似乎很奇怪,但是还有另外两个选择:

I've found a useful article which describes binding in more detail. It seems to suggest that the type converter is only used to convert "to" another type - so you'd need the type converter for string to know how to convert to the custom type. This seems pretty strange to me, admittedly, but there are two other options:


  • 使用Binding的Format和Parse事件进行转换

  • 使类型实现IConvertible

这两种都不会以相同的方式吸引,但他们可能会为您提供足够的解决方法。我相信有一种办法可以使用TypeConverters来工作,但如果我能看到它,我会被打击。

Neither of these appeal in quite the same way, but they may be enough of a workaround for you. I'm sure there's a way to get this to work using TypeConverters, but I'm blowed if I can see it at the moment.

这篇关于如何将自定义类型的数据绑定到TextBox.Text?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆