tengo un tipo personalizado C# como (es un ejemplo):¿Cómo enlaza un dato un tipo personalizado con TextBox.Text?
public class MyVector
{
public double X {get; set;}
public double Y {get; set;}
public double Z {get; set;}
//...
}
Y yo quiero que databind a TextBox.Text:
TextBox textBox;
public MyVector MyVectorProperty { get; set;}
//...
textBox.DataBindings.Add("Text", this, "MyVectorProperty");
Esencialmente necesito conversión hacia y desde una cadena de mi tipo de valor personalizado En el cuadro de texto, quiero algo como "x, y, z" que se puede editar para actualizar el tipo de vector. Supuse que podía hacerlo añadiendo una clase derivada 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);
}
}
y asociarlo con mi estructura:
[TypeConverter(typeof(MyVectorConverter))]
public class MyVector { //... }
Esto parece completar la mitad de la batalla. Puedo ver MyVectorConverter
llamando, pero algo anda mal. Se llama para ver si sabe cómo convertir a cadena, luego se llama para convertir a cadena. Sin embargo, nunca se consulta para ver si puede convertir FROM cadena ni hacer realmente la conversión. Además, justo después de una edición en el cuadro de texto, el valor anterior se reemplaza inmediatamente (otra secuencia CanConvertTo y ConvertTo, restaurando el valor anterior). El resultado final es que la entrada recién ingresada en el cuadro de texto se revierte inmediatamente después de que se aplica.
Siento como si simplemente faltara algo simple. ¿Esta ahí? ¿Todo este proyecto/enfoque está condenado al fracaso? ¿Alguien más intenta tal locura? ¿Cómo se vincula bi-direccionalmente un tipo personalizado de varias partes a un control basado en cadenas?
Solución: Curiosamente, todo lo que se necesita es que se habilite el "formateo" en el objeto de enlace. (Gracias, Jon Skeet):
textBox.DataBindings.Add("Text", this, "MyVectorProperty"); //FAILS
textBox.DataBindings.Add("Text", this, "MyVectorProperty", true); //WORKS!
Curiosamente, todo lo que mi MSDN menciona acerca de este parámetro (formattingEnabled) es:
"verdadero dar formato a los datos que, de lo contrario, falsa"
No menciona nada que sea un requisito para que los datos vuelvan del control (en estas condiciones).
Gracias por los comentarios, he aclarado el ejemplo y he hecho la pregunta más genérica. Mi ejemplo fue una estructura para la simplicidad, pero lo he cambiado a un tipo de referencia para demostrar el problema más amplio. – el2iot2
Hacerlo una estructura con campos públicos ciertamente no * agrega * a la simplicidad :) ¿Esto es en Windows Forms, WPF, ASP.NET o qué? –
Depende de lo que sea su heurística para "simplicidad" (simplicidad de código, simplicidad de ejemplo, simplicidad de uso del tipo de datos en interoperabilidad ... etc.), pero estoy divagando. Intento utilizar la solución en los formularios de Windows, pero la pregunta es relevante para la vinculación de datos en general, creo. – el2iot2