【问题标题】:How does one databind a custom type to TextBox.Text?如何将自定义类型数据绑定到 TextBox.Text?
【发布时间】:2010-10-02 23:08:13
【问题描述】:

我有一个自定义的 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 对象上启用“格式化”即可。 (感谢 Jon Skeet):

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

奇怪的是,我的 MSDN 提到的关于这个参数 (formattingEnabled) 的全部内容是:

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

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

【问题讨论】:

    标签: c# winforms data-binding textbox typeconverter


    【解决方案1】:

    知道了!

    Binding.FormattingEnabled 属性设置为true。这似乎使一切正常。 您可以通过重载ControlBindingsCollection.Add 方法来完成此操作,该方法最后采用布尔参数。 奇怪的是,它以一种方式工作,但以前不是另一种,但我的测试应用现在可以工作了......

    (下面的旧答案)

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

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

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

    这很可能不是问题的根源,但是使用带有公共字段的可变结构只是在 IMO 上自找麻烦。

    编辑:正如 cmets 中所述,我现在已经启动并运行了一个示例。 Binding.Parse 正在以正确的值引发。现在找出为什么没有调用 TypeConverter...

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

    • 使用 Binding 的 Format 和 Parse 事件进行转换
    • 使类型实现 IConvertible

    这两种方式都不一样,但它们可能足以成为您的解决方法。我确信有一种方法可以使用 TypeConverters 让它工作,但如果我现在能看到它,我会感到震惊。

    【讨论】:

    • 感谢您的反馈,我已经阐明了示例并使问题更加通用。为了简单起见,我的示例是一个结构,但我已将其更改为引用类型以演示更广泛的问题。
    • 把它变成一个带有公共字段的结构肯定不会添加简单:) 这是在 Windows 窗体、WPF、ASP.NET 还是什么?
    • 取决于您对“简单性”的启发式是什么(代码的简单性、示例的简单性、在互操作中使用数据类型的简单性等),但我离题了。我试图在 Windows 窗体中使用该解决方案,但我认为这个问题通常与数据绑定有关。
    • 可变结构很少意味着 any 上下文中的简单性。无论如何,我已经重现了这个问题,但我也无法让它工作。正如你所说,绑定似乎只在显示侧。还在寻找。
    • 确实,成功了。感谢您的帮助,我很感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-22
    • 1970-01-01
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 2011-06-18
    相关资源
    最近更新 更多