2009-04-03 5 views
19

Objective-c/cacao offre une forme de liaison où les propriétés d'un contrôle (texte dans une zone de texte) peuvent être liées à la propriété d'un objet. J'essaie de dupliquer cette fonctionnalité dans C# w/.Net 3.5.Liaison de données à un objet en C#

J'ai créé la classe suivante très simple dans le fichier MyClass.cs:

class MyClass 
{ 
    private string myName; 

    public string MyName 
    { 
     get 
     { 
      return myName; 
     } 

     set 
     { 
      myName = value; 
     } 
    } 

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

J'ai aussi créé un formulaire simple avec 1 et 1 bouton zone de texte. J'ai initié une instance de Myclass dans le code du formulaire et construit le projet. À l'aide de l'Assistant DataSource dans Vs2008, j'ai sélectionné pour créer une source de données basée sur l'objet et sélectionné l'assembly MyClass. Cela a créé une entité de source de données. J'ai changé la liaison de données de la zone de texte à cette source de données; Cependant, le résultat attendu (que le contenu de la zone de texte serait "allen") n'a pas été atteint. De plus, mettre du texte dans la zone de texte ne met pas à jour la propriété name de l'objet. Je sais qu'il me manque quelque chose de fondamental ici. À un moment donné, je devrais lier mon instance de la classe MyClass que j'ai initialisée dans le code du formulaire à la zone de texte, mais cela ne s'est pas produit. Tout ce que j'ai regardé en ligne semble passer en revue l'utilisation de DataBinding avec un objet (ou je manque complètement la marque), donc toute aide est très appréciée.

Edit:

En utilisant ce que j'appris par les réponses, je regardais le code généré par Visual Studio, il avait les éléments suivants:

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

si je commente cela et remplacer:

this.myClassBindingSource.DataSource = new MyClass(); 

Je reçois le comportement attendu. Pourquoi le code par défaut est-il généré par VS comme il est? En supposant que c'est plus correct que la méthode qui fonctionne, comment dois-je modifier mon code pour travailler dans les limites de ce que VS généré?

+0

Le code par défaut est géré de telle sorte que, au moment de la conception, tous les contrôles connaissent les différents types de propriétés qui seront accessibles à la base de données. Mais à l'exécution, vous avez besoin d'une instance réelle. Ne supprimez pas le code généré automatiquement, jsut définissez une nouvelle valeur dans votre formulaire onload ou soemthing –

Répondre

15

Vous devez affecter la source de données de la zone de texte à votre nouvelle source de données. En outre, vous devez affecter la source de données de la source de données à une instance de votre classe.

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

Cela devrait fonctionner pour votre premier passage. Comme d'autres l'ont mentionné, vous devrez peut-être implémenter des interfaces supplémentaires sur votre classe (INotifyPropertyChanged etc), si vous allez modifier les propriétés de la classe via n'importe quel processus d'arrière-plan.

Si vous mettez à jour uniquement les propriétés via le formulaire, vous n'avez pas besoin de cette étape.

+3

TextBox1.DataBindings.Add ("Text",> Votre objet <, "> PropertyName <";; –

12

Vous devez implémenter l'interface INotifyPropertyChanged à votre type de MyClass:

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

Cette interface est nécessaire pour l'infrastructure DataBinding si vous voulez soutenir databinding simple. L'interface INotifyPropertyChanged est utilisée pour notifier une 'liaison' qu'une propriété a modifiée, de sorte que l'infrastructure DataBinding peut agir en conséquence.

Ensuite, vous pouvez numériser la propriété MyName vers la propriété Text de la zone de texte.

0

On dirait que vous avez probablement besoin d'un attribut Bindable sur votre propriété monnom (et suivre la suggestion de Frederik ainsi):

[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

Je n'ai pas de code devant moi , mais je pense que la source de données est un peu comme une collection. Vous devez ajouter une instance de MyClass à la source de données, et c'est ce à quoi les champs de formulaire se lieront. Il existe également des méthodes pour naviguer à travers la source de données vers plusieurs instances de MyClass, mais cela ne semble pas être le cas. Vérifiez les documents pour DataSource.

Je ne pense pas que vous ayez besoin d'implémenter des interfaces sophistiquées. Il me semble me souvenir qu'il existe une méthode sur la source de données qui vous permet d'actualiser ou de relier l'élément actuel après avoir modifié certaines valeurs.

3

Je reçois un message d'erreur dans la méthode DataBinding.Add("TEXT", myObject, myObjectProperty)

Ceci est probablement parce que vous êtes absent explicite {get; set;} sur la déclaration de propriété!

BAD:

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

BON:

public string FirstName { get; set; } 
+0

chaîne publique FirstName; définit un champ, Vous avez raison, vous ne pouvez pas lier à un champ, mais ce n'est pas parce que ce n'est pas une "propriété explicitement déclarée". "public string FirstName;" n'est pas une propriété du tout! Si je peux suggérer quelque chose , si vous pouvez copier et coller le message d'erreur spécifique que vous receviez, cela pourrait aider quelqu'un à trouver votre message.Merci de contribuer, je suis sûr que votre note aidera en fait quelqu'un sur la route! –

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

Plus de détails vous pouvez lire dapfor tutoriel. com

Questions connexes