Comment puis-je lier une “liste” de chaînes à une zone de liste déroulante dans WPF?
En gros, j'ai envie de prendre un tas de noms dans une collection et de les lier à une zone de liste déroulante. Par exemple:
- Projet de loi
- Jack
- Bob
- Kevin
et avoir ces éléments dans une collection que ce soit lié à la zone de liste déroulante. Je ne suis pas sûr si la liste sera mis à jour de façon dynamique ou pas, mais je préfère le plan pour qu'il soit. Toute aide serait appréciée. J'ai essayé pendant quelques heures maintenant et ne peut pas le comprendre. Je veux le faire dans le code XAML et le code-behind. Dans le code-behind,
MyComboBox.ItemsSource = MyObservableCollection;
fonctionne très bien. Je ne sais pas comment le faire dans le code XAML mais avec la collection déclarée dans le code-behind.
Merci d'avance (encore une fois), de la communauté.
*EDIT:
C'est de cette façon que j'ai la collection déclaré et accessible.
public ObservableCollection<string> propertynames
{
get {return _propertynames;}
}
private ObservableCollection<string> _propertynames;
La dernière chose que j'ai essayé était ceci:
<Window.Resources>
<CollectionViewSource Source="{Binding propertynames}" x:Key="srcSort"/>
</Window.Resources>
....
<ComboBox x:Name="cboSort" HorizontalAlignment="Left" VerticalAlignment="Top"
Width="256" Background="WhiteSmoke" Margin="12,50,0,0" FontSize="12pt"
Height="27.28"
SelectedIndex="0"
SelectionChanged="cboWorkCenters_SelectionChanged"
ItemsSource="{Binding Path = {StaticResource srcSort}}">
</ComboBox>
....
Je suis un total n00b à ce genre de choses. Depuis environ une semaine, donc j'ai peut-être fait quelque chose de vraiment évident pour un utilisateur chevronné.
*EDIT #2
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:WpfApplication1"
Title="Window1" Height="226" Width="242"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<ComboBox Margin="43,71,40,77"
Name="comboBox1"
ItemsSource="{Binding ob}" />
</Grid>
</Window>
namespace WpfApplication1
{
///<summary>
///Interaction logic for Window1.xaml
///</summary>
public partial class Window1 : Window
{
public ObservableCollection<string> ob
{
get
{
return _ob;
}
}
private ObservableCollection<string> _ob = new ObservableCollection<string>();
public Window1()
{
InitializeComponent();
FillObj();
//comboBox1.ItemsSource = ob;
}
private void FillObj()
{
for (int i = 1; i < 6; i++)
{
_ob.Add(i.ToString());
}
}
}
}
Fait au-dessus de réel projet simple, juste pour voir si je faisais tout mal. Cela a bien fonctionné donc quelque chose d'autre doit être à l'origine de la panne.
*EDIT #3
*PROBLÈME RÉSOLU
Pour l'amour de Dieu, j'ai tout compris. J'ai été sur cela pendant des HEURES et c'est juste ridicule ce qui est la cause de la panne.
La solution est ceci: je n'ai pas l'instanciation de _propertynames quand je l'ai déclaré. J'ai été interrogeant les propriétés de la classe avec Linq pour obtenir la liste des propriétés et ensuite créé _propertynames en passant ...GetProperties.ToList<...>() dans le constructeur. Apparemment, vous avez pour instancier la variable de sorte à ce qu'il frappe au cours de InitializeComponent. Irréel.
Une fois que j'ai fait et ensuite ajouté les éléments après le fait, il a bien fonctionné.
Je souhaite WPF avait un visage si je pouvais le frapper. Je sais que c'est mon ignorance de la façon dont cela fonctionne, mais je ne pouvais vraiment avoir utilisé une sorte de message.
Merci les gars pour l'aider. Vos deux suggestions ont été utile une fois que j'ai pris soin de la racine.
private ObservableCollection<string> _propertynames
doit être
private ObservableCollection<string> _propertynames = new ObservableCollection<string>()
OriginalL'auteur Yatrix | 2011-07-27
Vous devez vous connecter pour publier un commentaire.
Il y a d'innombrables façons de le faire. Une fois que vous avez créé la collection dans le code-behind, vous pouvez:
Appel
Resources.Add
pour l'ajouter à la fenêtre du dictionnaire de ressources, et alors se lier à la ressource, par exempleItemsSource="{Binding {DynamicResource MyList}}"
.Donner la
ComboBox
un nom (à l'aide de lax:Name
attribut) et définir sonItemsSource
explicitement dans le code, par exempleMyComboBox.ItemsSource = myCollection;
.Créer une classe, de faire de la collecte d'une propriété de la classe, et la fenêtre du
DataContext
à une instance de cette classe et de se lier à elle directement, par exempleItemsSource = "{Binding MyCollectionProperty}"
.La collection, une propriété de la fenêtre, la fenêtre de
DataContext
àthis
, et de le lier à la propriété (ce qui est essentiellement la même technique n ° 3, seulement vous n'êtes pas créer une nouvelle classe).Sans réglage de la fenêtre du
DataContext
, vous pouvez toujours référence à une propriété sur à l'aide de la liaison tant que vous avez donné un nom, par exemple{Binding ElementName=MyWindow, Path=MyCollection}
. (C'est le même que Ross suggestion.)Ou, sans donner un nom à la fenêtre, vous pouvez utiliser
RelativeSource
de liaison pour trouver l'ancêtreWindow
et de se lier à une propriété sur elle. Je n'ai pas confiance en ma capacité à écrire un travail de liaison expression qui utiliseRelativeSource
sur le dessus de ma tête, donc je vais laisser ça comme un exercice pour le lecteur.Vous pouvez définir la
DataContext
de laComboBox
à l'exemple de votre collection, puis définissez sesItemsSource
à{Binding}
. Vous ne voudrez probablement pas à le faire dans la pratique; je le mentionne juste parce qu'il semble être une erreur commune pour les personnes à créer leDataContext
d'un contrôle sans définir également une liaison, et se demandent ensuite pourquoi le contenu de l'objet lié ne s'affiche pas.(Alors que j'ai dit "fenêtre" dans le ci-dessus, tout ce que j'ai dit est vrai aussi pour les commandes de l'utilisateur.)
Je suis sûr qu'il ya au moins cinq autres façons de le faire que je ne pense pas. La liaison est vraiment, vraiment souple.
Cela devrait fonctionner si la fenêtre du datacontext est fixé à lui-même (mettre ".Datacontext = this;" à l'intérieur de la fenêtre du constructeur).
<Fenêtre x:Classe=... ...DataContext="{Binding RelativeSource={RelativeSource Self}}"> Est ce que j'ai. Ce n'est pas l'accomplissement de la même chose?
Ajout de plus à la question ci-dessus. Voir sous Edit#2. Qui a bien fonctionné. Le combo rempli à partir de la collection comme prévu.
"... d'innombrables façons ... <liste Numérotée avec 7 points>", et de toute façon, n'est-ce pas là quelque chose qui manque dans la première liaison? c'est à dire
Source=
OriginalL'auteur Robert Rossney
Ce que vous avez essayé jusqu'à présent?
Je l'approche de la façon suivante, en supposant que la zone de liste déroulante dans un UserControl avec un code-behind de la classe contenant la public propriété
MyObservableCollection
:OriginalL'auteur Ross