2009-04-03 18 views
19

Objective-c/cacao offre una forma di legame in cui le proprietà di un controllo (ad es. Testo in una casella di testo) possono essere associate alla proprietà di un oggetto. Sto cercando di duplicare questa funzionalità in C# con .Net 3.5.Associazione dati a un oggetto in C#

Ho creato la seguente classe molto semplice nelle MyClass.cs di file:

class MyClass 
{ 
    private string myName; 

    public string MyName 
    { 
     get 
     { 
      return myName; 
     } 

     set 
     { 
      myName = value; 
     } 
    } 

    public MyClass() 
    { 
     myName = "Allen"; 
    } 
} 

Ho anche creato un semplice modulo con 1 casella di testo e 1 pulsante. Ho avviato un'istanza di Myclass all'interno del codice del modulo e ho creato il progetto. Utilizzando la procedura guidata DataSource in Vs2008, ho scelto di creare un'origine dati basata su oggetto e selezionato l'assembly MyClass. Questo ha creato un'entità dell'origine dati. Ho cambiato l'associazione dati della casella di testo a questa origine dati; tuttavia, il risultato atteso (che il contenuto della casella di testo sarebbe "allen") non è stato raggiunto. Inoltre, inserire del testo nella casella di testo non sta aggiornando la proprietà del nome dell'oggetto.

So che mi manca qualcosa di fondamentale qui. Ad un certo punto dovrei legare la mia istanza della classe MyClass che ho inizializzato all'interno del codice del modulo nella casella di testo, ma ciò non si è verificato. Tutto ciò che ho visto online sembra sorvolare usando DataBinding con un oggetto (o mi manca completamente il marchio), quindi ogni aiuto è molto apprezzato.

Edit:

Utilizzando quello che ho imparato dalle risposte, ho guardato il codice generato da Visual Studio, aveva il seguente:

this.myClassBindingSource.DataSource = typeof(BindingTest.MyClass); 

se io commento che fuori e sostituto:

this.myClassBindingSource.DataSource = new MyClass(); 

Ottengo il comportamento previsto. Perché il codice predefinito generato da VS è come lo è? Supponendo che questo sia più corretto del metodo che funziona, come dovrei modificare il mio codice per funzionare entro i limiti di ciò che VS ha generato?

+0

Il codice predefinito viene gestito in questo modo in modo che in fase di progettazione tutti i controlli conoscano i vari tipi di proprietà che saranno disponibili per il database. Ma in fase di esecuzione è necessaria un'istanza reale. Non rimuovere il codice generato automaticamente, jsut imposta un nuovo valore nel tuo modulo onload o soemthing –

risposta

15

È necessario assegnare l'origine dati della casella di testo come nuova origine dati. Ma in aggiunta, è necessario assegnare l'origine dati dell'origine dati per essere un'istanza della classe.

MyDataSource.DataSource = new MyClass(); 
TextBox1.DataSource = MyDataSource; 

Questo dovrebbe funzionare per il primo passaggio. Come altri hanno già detto, potrebbe essere necessario implementare interfacce aggiuntive sulla classe (INotifyPropertyChanged ecc.), Se si stanno modificando le proprietà della classe tramite qualsiasi processo in background.

Se si stanno solo aggiornando le proprietà tramite il modulo, non è necessario questo passaggio.

+3

TextBox1.DataBindings.Add ("Testo",> Il tuo oggetto <, "> PropertyName <"); –

12

Si dovrebbe implementare l'interfaccia INotifyPropertyChanged al tipo MyClass: è richiesto

public class MyClass : INotifyPropertyChanged 
{ 
    private string _myName; 

    public string MyName 
    { 
     get { return _myName; } 
     set 
     { 
      if(_myName != value) 
      { 
       _myName = value; 
       OnPropertyChanged("MyName"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void OnPropertyChanged(string propertyName) 
    { 
     if(PropertyChanged != null) 
      PropertyChanged(this , new PropertyChangedEventArgs(propertyName)); 
    }  
} 

Questa interfaccia per l'infrastruttura DataBinding se si desidera supportare semplice associazione dati. L'interfaccia INotifyPropertyChanged viene utilizzata per notificare a un 'associazione' che una proprietà è stata modificata, pertanto l'infrastruttura DataBinding può agire di conseguenza.

Quindi, è possibile associare la proprietà MyName alla proprietà Text della casella di testo.

0

Sembra che probabilmente avete bisogno di un attributo Bindable sulla vostra proprietà MyName (e seguire il suggerimento di Frederik pure):

[System.ComponentModel.Bindable(true)] 
    public string MyName 
    { 
     get { return _myName; } 
     set 
     { 
      if(_myName != value) 
      { 
       _myName = value; 
       OnPropertyChanged("MyName"); 
      } 
     } 
    } 

Via: http://support.microsoft.com/kb/327413

0

non ho alcun codice di fronte a me , ma penso che la fonte dei dati sia un po 'come una collezione. Devi aggiungere un'istanza di MyClass all'origine dati, e questo è ciò a cui i campi modulo si collegheranno. Esistono anche metodi per navigare attraverso l'origine dati a più istanze di MyClass, ma non sembra che tu ne abbia bisogno. Controlla i documenti per DataSource.

Non penso che sia necessario implementare interfacce di fantasia. Mi sembra di ricordare che esiste un metodo sull'origine dati che consente di aggiornare o riassociare l'elemento corrente dopo aver modificato alcuni valori.

3

ricevo un messaggio di errore nel metodo DataBinding.Add("TEXT", myObject, myObjectProperty)

Questo probabilmente è perché ti manca l'esplicita {get; set;} sulla dichiarazione di proprietà!

BAD:

public string FirstName; //<-- you will not be able to bind to this property! 

BUONO:

public string FirstName { get; set; } 
+0

stringa pubblica FirstName; definisce un campo, non è una proprietà. È corretto che non è possibile associare a un campo, ma non è perché non è una "proprietà dichiarata esplicitamente". "public string FirstName;" non è affatto una proprietà! Se posso suggerire qualcosa , se riesci a copiare e incollare il messaggio di errore specifico che stavi ricevendo, questo potrebbe aiutare qualcuno a cercare il tuo post. Grazie per il contributo, sono sicuro che la tua nota aiuterà effettivamente qualcuno in fondo alla strada! –

0
using System.Collections.Generic; 

public class SiteDataItem 
{ 
private string _text; 
private string _url; 
private int _id; 
private int _parentId; 

public string Text 
{ 
    get 
    { 
     return _text; 
    } 
    set 
    { 
     _text = value; 
    } 
} 

public string Url 
{ 
    get 
    { 
     return _url; 
    } 
    set 
    { 
     _url = value; 
    } 
} 
public int ID 
{ 
    get 
    { 
     return _id; 
    } 
    set 
    { 
     _id = value; 
    } 
} 
public int ParentID 
{ 
    get 
    { 
     return _parentId; 
    } 
    set 
    { 
     _parentId = value; 
    } 
} 
public SiteDataItem(int id, int parentId, string text, string url) 
{ 
    _id = id; 
    _parentId = parentId; 
    _text = text; 
    _url = url; 
} 

public static List<SiteDataItem> GetSiteData() 
{ 
    List<SiteDataItem> siteData = new List<SiteDataItem>(); 
    siteData.Add(new SiteDataItem(1, 0, "All Sites", "")); 
    siteData.Add(new SiteDataItem(2, 1, "Search Engines", "")); 
    siteData.Add(new SiteDataItem(3, 1, "News Sites", "")); 
    siteData.Add(new SiteDataItem(4, 2, "Yahoo", "http://www.yahoo.com")); 
    siteData.Add(new SiteDataItem(5, 2, "MSN", "http://www.msn.com")); 
    siteData.Add(new SiteDataItem(6, 2, "Google", "http://www.google.com")); 
    siteData.Add(new SiteDataItem(7, 3, "CNN", "http://www.cnn.com")); 
    siteData.Add(new SiteDataItem(8, 3, "BBC", "http://www.bbc.co.uk")); 
    siteData.Add(new SiteDataItem(9, 3, "FOX", "http://www.foxnews.com")); 
    return siteData; 
} 
} 

Maggiori dettagli si possono leggere dapfor tutorial. com

Problemi correlati