2009-03-30 8 views
5

Imaginez ces deux classes:obligatoire dans WinForms Dropdown

class Part 
{ 
public string Name { get; set;} 
public int Id { get; set; } 
} 

class MainClass 
{ 
public Part APart { get; set;} 
} 

Comment puis-je lier MainClass à une zone de liste déroulante sur un WinForm, il affiche Part.Name (DisplayMember = "Name";) et l'élément sélectionné de la liste déroulante définit la APart propriété de la MainClass sans avoir besoin de gérer les événements sur la liste déroulante. Pour autant que je sache, définir ValueMember de ComboBox sur "Id" signifie qu'il va essayer de mettre APart à un nombre (Id) qui n'est pas correct.

Espérons que c'est assez clair!

+0

Bonne question. J'ai toujours fait des choses par id jamais par des objets. – Tony

+0

quelqu'un peut-il changer "propriété" dans le code à "public"? – Sung

Répondre

1

Ce que vous cherchez, c'est que le ValueMember (= ComboBox.SelectedItem) soit une référence à l'objet lui-même, tandis que DisplayMember est une propriété unique de l'article, c'est correct? Pour autant que je sache, il n'y a pas de bon moyen de le faire sans créer votre propre ComboBox et de faire la liaison vous-même, en raison de la manière ValueMember et DisplayMember de travail.

Mais, voici quelques choses que vous pouvez essayer (en supposant que vous avez une collection de Part s quelque part):

  1. Remplacer la méthode `ToString()` de `Part` pour renvoyer le` Nom `propriété. Ensuite, définissez votre `ComboBox`` ValueMember` à `" APart "` et laissez null DisplayMember`. (Non testé, donc sans garantie)
  2. Vous pouvez créer une nouvelle propriété dans Part pour renvoyer une référence à elle-même. Définissez 'ValueMember' sur la nouvelle propriété et 'DisplayMember' sur `" Name "`. Cela peut sembler un peu un hack, mais ça devrait marcher.
  3. Faites des choses amusantes avec votre getter et setter `APart`. Vous perdrez un typage fort, mais si vous faites un objet APart et que MainClass contient la collection de Parts, vous pouvez le définir par Id (int) ou Part. (Évidemment, vous aurez envie d'être mise par Id lorsque vous liez la zone de liste déroulante à lui.)
Part _APart; 
object APart 
{ 
    get {return _APart;} 
    set { 
     if(value is int) 
      _APart = MyPartCollection.Where(p=>p.Id==value).Single(); 
     else if(value is Part) 
      _APart = value; 
     else 
      throw new ArgumentException("Invalid type for APart"); 
    } 
} 
0

J'ai fait un peu de recherche et trouvé this article où l'auteur a été capable de se lier à des propriétés imbriquées en étendant le composant source de liaison standard.
Je l'ai essayé et cela semble fonctionner correctement.

0

Si vous définissez la ValueMember de la zone de liste déroulante à null, la liaison de données renverra l'élément sélectionné (c'est-à-dire l'instance Part) au lieu du membre spécifié. Définissez DisplayMember sur "Name".

+0

Pouvez-vous fournir un extrait de travail de ceci s'il vous plaît? Je ne peux pas le faire pour faire ce que vous dites en réglant ValueMember sur null. – Khash

0

créer une classe de sauvegarde pour contenir les "informations" et créer des propriétés pour toutes les données. Ensuite, mettre en œuvre System.ComponentModel.INotifyPropertyChanged sur cette classe, quelque chose comme:

private String _SelectedPart = String.Empty; 

public String SelectedPart 
{ 
    get 
    { 
     return _SelectedPart; 
    } 
    set 
    {    
     if (_SelectedPart != value) 
     { 
     _SelectedPart = value; 

     // helper method for handing the INotifyPropertyChanged event 
     PropertyHasChanged(); 
     } 
    } 
} 

Ensuite, créez un pour cette classe « ObjectDataSource » (Shift-Alt-D VS2008 va soulever cette question en regardant un formulaire), puis cliquez sur votre ComboBox et définissez les propriétés suivantes:

DataSource, défini sur ObjectDataSource "BindingSource" que vous venez de créer. DisplayMember, Définir sur la propriété Nom de la liste de pièces ValueMember, Définissez sur le membre ID de la liste des pièces DataBindings.SelectedValue, définissez la SelectedPart sur la "BindingSource" que vous venez de créer.Je sais que ce qui précède semble complexe, et cela pourrait prendre un peu de temps pour trouver toutes les parties que je viens de décrire (j'aimerais pouvoir donner un tutoriel ou une capture d'écran), mais vraiment c'est TRÈS rapide à faire . Ceci est d'ailleurs considéré comme "liaison de données" dans .NET et il y a quelques bons tutoriels qui peuvent donner plus d'informations.

+0

Merci pour votre message sur la liaison de données. Toutefois, cela ne répond pas à la question qui concerne la liaison à l'objet de recherche par opposition à l'ID de l'objet de recherche. – Khash