2009-01-22 15 views
7

Ben (tıpkı bir örnek) gibi özel bir C# türü var:Bir TextBox.Text için özel bir tür nasıl bir veritabanını oluşturur?

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

Ve bunun TextBox.Text için databind istiyorum:

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

Esasen ben ve bir dizesinden dönüşüm ihtiyaç özel değer türüm. Metin kutusuna, vektör türünü güncellemek için düzenlenebilir "x, y, z" gibi bir şey istiyorum.

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

ve benim yapı ile ilişkilendirerek: Ben TypeConverter türetilmiş bir sınıf ekleyerek yapabileceğini farz

Bu savaş yarısı tamamlamak için görünür
[TypeConverter(typeof(MyVectorConverter))] 
public class MyVector { //... } 

. MyVectorConverter'u arayarak görebilirsiniz, ama bir şey yanlış. Dize nasıl dönüştürüleceğini bilir, sonra dize dönüştürmek için denir. Ancak, FROM dizgesini dönüştürüp dönüştüremediğini veya dönüştürmeyi gerçekleştirip gerçekleştiremeyeceğini asla sorgulamamaktadır. Bundan başka, sağ metin bir düzenleme sonra, eski değer hemen (eski değer geri başka CanConvertTo ve ConvertTo sekansı) değiştirilir. Son sonuç, metin kutusuna yeni yazılan girdinin uygulandıktan hemen sonra geri döndürülmesidir. Sadece eksik basit bir şey yokmuş gibi

hissediyorum. Var mı? Tüm bu proje/yaklaşım başarısızlığa mahkum mu? Böyle bir çılgınlık yapan başka biri var mı? Bir dize tabanlı denetime özel, çok parçalı bir türden iki yönlü olarak nasıl bağlanır?

Çözüm: Bunda gerekli olan tek şey, "biçimlendirme" nin Binding nesnesinde etkinleştirilmesidir. (Teşekkürler, Jon Skeet): İşin garibi

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

, benim MSDN Bu parametrenin (formattingEnabled) bahseder hepsi bu:

"gerçek görüntülenen verileri biçimlendirmek için, aksi takdirde false"

veri (bu koşullar altında) kontrolden geri gelmek için bir gereklilik olduğu hakkında hiçbir şey bahseder.

cevap

10

Anladım!

Seti true Binding.FormattingEnabled özelliği. Bu hepsi işe yarıyor gibi görünüyor. Sen sonunda bir Boole parametre alır ControlBindingsCollection.Add yöntemine aşırı yapabilirsiniz. ... O önce diğer bir şekilde çalıştı ama o garip, ama kesinlikle benim test uygulaması artık çalışıyor

(aşağıda Eski yanıt) Ben hiç şaşırmam

eğer size gerçeği Burada bir sınıf yerine bir yapının olması, özelliklerin yerine alanları kullanmanın yanı sıra burada da önemliydi.

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

Bu kuyu sorunun kök olmayabilir, ama kamu alanları ile kesilebilir bir yapı ile sadece IMO sorun istiyor:

bir sınıf yerine autoimplemented özelliklerini kullanarak deneyin.

DÜZENLEME: Yorumlarda belirtildiği gibi, şimdi bir örnek alıyorum ve çalışıyor. Binding.Parse doğru değerle yükseltiliyor. Şimdi TypeConverter'in neden çağrılmadığını öğrenmek için ...

DÜZENLEME: Daha fazla ayrıntıda bağlamayı tanımlayan bir useful article buldum. Bu tür dönüştürücünün yalnızca başka bir türe "dönüştürmek için" kullanıldığını öne sürüyor - bu nedenle, özel türe nasıl dönüştürüleceğini öğrenmek için string için tür çeviricisine ihtiyacınız var. Bu kuşkusuz, bana oldukça garip görünüyor, ancak diğer iki seçenek vardır:

  • Format kullanın ve tip

Ne ait IConvertible uygulamak olun dönüşüme

  • yapmak Bağlama olaylarını Ayrıştırma Bu itirazlar aynı şekilde, ancak sizin için bir geçici çözüm olabilir. Eminim bunu TypeConverters kullanarak çalışmak için bir yol var, ama şu anda görebiliyorsam, uçurum.

  • +0

    Geri bildiriminiz için, örneği açıklığa kavuştum ve soruyu daha genel hale getirdim. Örneğim basitlik için bir yapıydı, ancak daha geniş bir problemi göstermek için bunu bir referans türüne dönüştürdüm. – el2iot2

    +0

    Kamu alanları ile bir yapı oluşturmak kesinlikle * basitlik * eklemez * Bu Windows Forms, WPF, ASP.NET veya nedir? –

    +0

    "Basitlik" in ne kadar sezgisel olduğuna bağlıdır (kodun sadeliği, basitlik, basitlik, veri tipinin interop..etc'de kullanılmasının basitliği), ama ben digress. Çözümü windows formlarında kullanmaya çalışıyorum, ama soru genel olarak veri bağlama ile ilgili, sanırım. – el2iot2

    İlgili konular