Wie macht man databind einen benutzerdefinierten Typ TextBox.Text?
Habe ich eine benutzerdefinierte c# - Typ wie (nur ein Beispiel):
public class MyVector
{
public double X {get; set;}
public double Y {get; set;}
public double Z {get; set;}
//...
}
Und ich will es databind-Methode, um die TextBox.Text:
TextBox textBox;
public MyVector MyVectorProperty { get; set;}
//...
textBox.DataBindings.Add("Text", this, "MyVectorProperty");
Im wesentlichen brauche ich die Konvertierung in und aus einer Zeichenfolge für meinen eigenen Wert geben. In der text-box, ich möchte etwas wie "x, y, z" kann bearbeitet werden, aktualisieren Sie die Vektor-Typ. Ich dachte, ich könnte so tun, indem Sie hinzufügen einer TypeConverter
abgeleitete Klasse:
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);
}
}
und verknüpfen es mit meinem struct:
[TypeConverter(typeof(MyVectorConverter))]
public class MyVector { //... }
Diese scheint komplett die Hälfte der Schlacht. Ich kann sehen MyVectorConverter
immer genannt, aber etwas nicht in Ordnung ist. Es wird aufgerufen, um zu sehen, ob es weiß, wie es zu konvertieren zu einem string, dann heisst es konvertieren zu einem string. Es ist jedoch nie abgefragt, um zu sehen, ob es kann konvertieren VON string noch um die eigentliche Konvertierung. Zudem, direkt nach einer Bearbeitung in der textbox, wird der alte Wert wird sofort ersetzt (andere CanConvertTo und ConvertTo-Sequenz, die Wiederherstellung der Alter Wert). Das Endergebnis ist, dass die neu eingegebenen Eintrag in die text box wird zurückgesetzt, sofort nachdem es angewendet wird.
Ich fühle mich, als wenn es nur einfach etwas fehlt. Ist es? Ist das ganze Projekt/Ansatz zum scheitern verurteilt? Hat jemand Versuch einen solchen Wahnsinn? Wie macht man bi-direktional binden eines benutzerdefinierten, multipart-Typ in einen string-basierten Steuerung?
Lösung: Bizarr, alles, was nötig ist für die "Formatierung" aktiviert werden über das Binding-Objekt. (danke, Jon Skeet):
textBox.DataBindings.Add("Text", this, "MyVectorProperty"); //FAILS
textBox.DataBindings.Add("Text", this, "MyVectorProperty", true); //WORKS!
Seltsam, alle, die meine MSDN erwähnt zu diesem parameter (formattingEnabled) ist:
"treu format die Daten angezeigt; andernfalls wird "false"
Er erwähnt nichts über es wird eine Anforderung für die Daten zu kommen zurück von der Kontrolle (unter diesen Bedingungen).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hab!
Legen Sie die
Bindung.FormattingEnabled
- Eigenschaft auf true. Dies scheint, um Sie alle Arbeit.Sie können dies mit einer überlastung der
ControlBindingsCollection.Add
Methode, die einen Boolean-parameter am Ende.Es ist seltsam, dass es funktioniert, eine Möglichkeit, aber nicht die anderen vorher, aber auf jeden Fall ist meine test-app funktioniert jetzt...
(Alte Antwort unten)
Ich gar nicht überrascht, wenn die Tatsache, dass Sie bekam ein struct statt der Klasse war hier wichtig - ebenso wie die Weise, die Sie mit Hilfe der Felder anstelle von Eigenschaften.
Versuchen mit einer Klasse mit autoimplemented Eigenschaften statt:
Kann dies auch nicht die Wurzel des Problems, sondern über eine veränderliche Struktur, die mit öffentlichen Feldern ist nur ärger bringen, IMO.
EDIT: Wie erwähnt in den Kommentaren, ich habe hier jetzt ein Beispiel und läuft. Die Bindung.Parse ist angehoben, mit dem richtigen Wert. Nun, um herauszufinden, warum die TypeConverter-nicht genannt wird...
EDIT: habe ich gefunden, nützliche Artikel beschreibt die Bindung im detail. Es scheint nahe zu legen, dass der Typ Konverter wird nur verwendet, um zu konvertieren", um" eine andere Art - so müssten Sie die Typ-Konverter für
string
wissen, wie zu konvertieren, um den benutzerdefinierten Typ an. Das scheint ziemlich seltsam zu mir, zugegebenermaßen, aber es gibt zwei andere Optionen:Weder dieser Appell in ganz der gleichen Weise, aber Sie kann genug sein, einen workaround für dich. Ich bin sicher, es gibt einen Weg, um dieses zu erhalten, um die Arbeit mit TypeConverters, aber ich bin blowed, wenn ich es sehen kann, im moment.