Je pense que vous avez tout en place dans votre question pour ajouter des éléments au Canvas
de votre ListBox
. Je viens de mettre en place une application de test WPF simple en utilisant le code dans votre question, et cela a juste fonctionné. Chaque fois que j'ai ajouté des éléments au ObservableCollection
qui est lié au ItemsSource
du ListBox
, WPF créerait un ListBoxItem
pour cet objet, et basé sur le style du ListBoxItem
, l'élément serait dessiné à l'emplacement correct par le Canvas
.
N'avez-vous pas réussi à faire fonctionner votre code? Si c'est le cas, quelle erreur avez-vous eu, ou qu'est-ce qui n'a pas fonctionné comme vous l'attendiez?
Édition: Après avoir relu la question, je pense que la confusion est due à une mauvaise compréhension du fonctionnement de la liaison WPF. Lorsque vous liez une collection à ItemsSource
de ListBox
, tout ce que vous devez faire est d'ajouter des éléments à cette collection (en supposant que la collection implémente INotifyCollectionChanged
, ce que fait ObservableCollection
). WPF s'abonne aux événements fournis par cette interface et crée/détruit ListBoxItems
en fonction des modifications apportées à la liste.
Edit 2: Il serait préférable d'utiliser un pour cette DataTemplate
, de sorte que la ligne sera ajoutée automatiquement lorsqu'un élément est ajouté à la collection, je ne sais pas comment vous pourriez obtenir la position de l'élément précédemment ajouté afin que la ligne commence au bon endroit.
Une option qui pourrait fonctionner serait de sous-classer Canvas
, et définir cela comme ItemsPanelTemplate
pour le ListBox
. Je crois qu'il a une fonction que vous pouvez remplacer qui est appelée chaque fois qu'un contrôle y est ajouté. Dans cette fonction, vous pouvez obtenir la position du contrôle précédemment ajouté (qui serait mis en cache dans votre sous-classe Canvas
), puis ajouter directement au contrôle de ligne pour les contrôles du Canvas
. Cela suppose que la position des contrôles dans le Canvas
ne peut pas changer. S'ils le peuvent, vous devrez probablement vous abonner à l'événement PropertyChanged
de l'objet et mettre à jour les lignes en conséquence.
Éditer 3: Puisque la liaison ne semble pas une option en raison de vos besoins, la moindre mauvaise option consiste à ajouter les enfants directement. Vous pouvez le faire en effectuant une recherche à travers l'arbre visuel en utilisant VisualTreeHelper.GetChild():
private T FindChild<T>(FrameworkElement parent, string name)
where T : FrameworkElement
{
FrameworkElement curObject = null;
T obj = default(T);
int count = VisualTreeHelper.GetChildrenCount(parent);
for(int i = 0; i < count; i++)
{
curObject = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
obj = curObject as T;
if(null != obj && obj.Name.Equals(name))
{
break;
}
obj = FindChild<T>(curObject, name);
if(null != obj)
{
break;
}
}
return obj;
}
Utilisez comme ceci:
Canvas canvas = FindChild<Canvas>(lstAwesome, "cnvAwesome");
Ce code recherche récursive à travers l'arbre visuel de parent
pour un contrôle du type et prénom. Il serait préférable d'utiliser ici DependencyObject
sur FrameworkElement
(puisque c'est ce qui est retourné par VisualTreeHelper.GetChild()
), cependant Name
est seulement défini sur FrameworkElement
.
Si vous voulez vous faire plaisir, vous pouvez même en faire une méthode d'extension.
Hey Andy, merci de vérifier cela. Et, oui, les éléments s'affichent correctement pour moi aussi. Ce que je demande, c'est si je peux ajouter des UIElements supplémentaires à la toile, * en plus * des ListItems. Je ne semble pas être en mesure d'obtenir une référence à cnvAwesome (voir xaml) –
Serait-il utile de modifier le ItemsPanelTemplate pour y ajouter les éléments sur le Canvas? Sinon, si vous voulez ajouter un contrôle supplémentaire par ListBoxItem, je vous suggérerais de suivre l'approche d'idursun et de modifier le DataTemplate afin que les contrôles supplémentaires soient automatiquement ajoutés chaque fois que vous ajoutez un élément à la collection. – Andy
Je voudrais suivre l'exemple d'idursun, mais ces UIElements devraient être ajoutés de manière procédurale, lors de l'exécution. Plus précisément, lorsqu'un élément est ajouté à la collection à laquelle ListBox est lié. Je ne peux pas obtenir un handle sur le ItemsPanel que ListBox utilise, et suis incapable d'ajouter UIElements à lui. J'apprécie vraiment l'aide, et s'il vous plaît laissez-moi savoir si je peux rendre mon problème plus clair. –