La liaison de données pour SelectedItem dans un WPF Treeview
Comment puis-je récupérer l'élément sélectionné dans WPF treeview? Je veux le faire en XAML, parce que je veux le lier.
Vous pourriez penser qu'il est SelectedItem
mais apparemment ce n'existe pas est en lecture seule et donc inutilisable.
C'est ce que je veux faire:
<TreeView ItemsSource="{Binding Path=Model.Clusters}"
ItemTemplate="{StaticResource ClusterTemplate}"
SelectedItem="{Binding Path=Model.SelectedCluster}" />
Je veux lier la SelectedItem
à une propriété sur mon Modèle.
Mais cela me donne l'erreur:
'SelectedItem" la propriété est en lecture seule et ne peut pas être définie à partir de la majoration.
Edit:
Ok, c'est le moyen que j'ai résolu ce problème:
<TreeView
ItemsSource="{Binding Path=Model.Clusters}"
ItemTemplate="{StaticResource HoofdCLusterTemplate}"
SelectedItemChanged="TreeView_OnSelectedItemChanged" />
et dans le codebehindfile de mon xaml:
private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
Model.SelectedCluster = (Cluster)e.NewValue;
}
- L'homme, cet suce. Il vient de frapper moi aussi. Je suis venu ici en espérant trouver qu'il ya une bonne façon et je suis juste un idiot. C'est la première fois que je suis triste de constater que je ne suis pas un idiot..
- cette suce vraiment et gâcher la liaison concept
- Espérons que cela pourrait aider quelqu'un à se lier à un arbre afficher l'élément sélectionné changé de retour d'appel sur Icommand jacobaloysious.wordpress.com/2012/02/19/...
- En termes de liaison et de MVVM, le code n'est pas "interdit", plutôt de code derrière devrait soutenir la vue. À mon avis, de toutes les autres solutions que j'ai vu, le code derrière est bien meilleure option, car elle est toujours aux prises avec la "liaison" de la vue vers le viewmodel. Le seul point négatif est que si vous avez une team avec un concepteur de travailler uniquement dans le code XAML, le code derrière pourrait obtenir cassée ou négligées. C'est un petit prix à payer pour une solution qui prend 10 secondes à mettre en œuvre.
- L'une des solutions les plus simples sans doute: stackoverflow.com/questions/1238304/...
Vous devez vous connecter pour publier un commentaire.
Je me rends compte de ce qui a déjà eu une réponse acceptée, mais j'ai mis cela ensemble pour résoudre le problème. Il utilise une idée similaire à Delta est la solution, mais sans la nécessité de la sous-classe le TreeView:
Vous pouvez ensuite l'utiliser dans votre XAML comme:
Espérons que cela va aider quelqu'un!
SelectedItem
sur le modèle de vue n'est pas réfléchie sur l'INTERFACE utilisateur.Mode=TwoWay
est réglé.{Binding SelectedItem, Mode=TwoWay}
avec{Binding MyViewModelField, Mode=TwoWay}
xmlns:e="http://schemas.microsoft.com/expression/2010/interactivity"
Cette propriété existe : TreeView.SelectedItem
Mais il est en lecture seule, donc vous ne pouvez pas affecter par une liaison, seulement récupérer
TreeView.SelectedItem
affecter une propriété sur le modèle lorsque l'utilisateur sélectionne un élément (akaOneWayToSource
)?Bien, j'ai trouvé une solution. Il se déplace le désordre, de sorte que MVVM œuvres.
D'abord ajouter cette classe:
et les ajouter à votre xaml:
Réponse avec des propriétés attachées et sans dépendances externes, si besoin est!
Vous pouvez créer une propriété attachée qui est peut être liée et a un getter et setter:
Ajouter la déclaration d'espace de noms contenant la classe de votre XAML et lier comme suit (local est ainsi que j'ai nommé la déclaration d'espace de noms):
Maintenant, vous pouvez lier l'élément sélectionné, et aussi le mettre dans votre modèle de vue de modifier par programmation, cette exigence devrait jamais survenir. C'est, bien sûr, en supposant que vous implémenter INotifyPropertyChanged sur ce bien particulier.
TreeViewItem
pour être sélectionné dans laTreeViewSelectedItemBehavior
classe est (dans mon expérience), toujoursnull
. Cela peut être parce queItemContainerGenerator
renvoie uniquement les éléments qui ont été générés visuellement, mais je ne suis pas vraiment sûr. +1 pour le reste de toute façon.Il répond à un peu plus de l'OP attend... Mais j'espère qu'elle pourra aider quelqu'un à moins.
Si vous souhaitez exécuter une
ICommand
chaque fois que leSelectedItem
changé, vous pouvez lier une commande sur un événement et l'utilisation d'une propriétéSelectedItem
dans leViewModel
n'est plus nécessaire.De le faire:
1 - Ajouter une référence à
System.Windows.Interactivity
2 - Lier la commande à l'événement
SelectedItemChanged
E DPS ENFIA O CODIG ONO CU NE
System.Windows.Interactivity
peut être installé à partir de NuGet: nuget.org/packages/System.Windows.Interactivity.WPFCe qui peut être accompli dans un agréable chemin en utilisant uniquement la liaison et le GalaSoft MVVM Light bibliothèque EventToCommand. Dans votre VM ajouter une commande qui sera appelée lorsque l'élément sélectionné est modifié, et initialiser la commande à effectuer toutes les démarches nécessaires. Dans cet exemple j'ai utilisé un RelayCommand et il suffit de régler le SelectedCluster propriété.
Puis ajouter le EventToCommand comportement dans votre xaml. C'est vraiment facile à l'aide d'un mélange.
Toutes compliqué... Aller avec Caliburn Micro (http://caliburnmicro.codeplex.com/)
Vue:
ViewModel:
Je suis tombé sur cette page à la recherche pour la même réponse que l'auteur original, et de prouver il y a toujours plus d'une façon de le faire, la solution pour moi a été de même plus facile que les réponses fournies jusqu'ici, j'ai donc pensé que je pourrais ajouter à la pile.
La motivation pour la liaison est de garder belle & MVVM. La probable utilisation du ViewModel est d'avoir une propriété w/un nom tel que "CurrentThingy", et d'autre part, le DataContext sur quelque chose d'autre est lié à "CurrentThingy".
Plutôt que de passer par des étapes supplémentaires requises (par exemple: comportement personnalisé, 3ème contrôle du parti) à l'appui d'une agréable reliure de l'Arborescence de mon Modèle, puis à partir de quelque chose d'autre à mon Modèle, ma solution a été d'utiliser simple Élément de liaison de l'autre chose à TreeView.SelectedItem, plutôt que de liaison de l'autre chose à mon ViewModel, en sautant ainsi le travail supplémentaire nécessaire.
XAML:
Bien sûr, ce qui est excellent pour la lecture de l'élément actuellement sélectionné, mais ne pas le mettre, ce qui est tout ce dont j'avais besoin.
Vous pourriez également être en mesure d'utiliser TreeViewItem.Propriété IsSelected
Il est aussi un moyen de créer XAML peut être liée propriété SelectedItem sans l'aide de l'Interaction.Les comportements.
Vous pouvez ensuite l'utiliser dans votre XAML comme:
J'ai essayé toutes les solutions de cette question. Personne n'a résolu mon problème entièrement. Donc, je pense que c'est mieux d'utiliser de tels hérité de la classe avec redéfini la propriété SelectedItem. Il fonctionnera parfaitement si vous choisissez de l'arbre de l'élément de l'interface graphique et si vous définissez cette valeur de propriété dans votre code
Mon exigence était pour PRISM-MVVM solution à base d'où un TreeView était nécessaire et l'objet lié est de type Collection<>, et par conséquent, les besoins HierarchicalDataTemplate. La valeur par défaut BindableSelectedItemBehavior ne sera pas en mesure d'identifier l'enfant TreeViewItem. Pour se rendre à travailler dans ce scénario.
Ceci permet de parcourir tous les éléments quel que soit le niveau.
- Je suggérer un plus pour le comportement fournis par Steve Greatrex. Son comportement ne reflète pas les changements à partir de la source car il peut ne pas être une collection de TreeViewItems.
C'est donc une question de trouver la TreeViewItem dans l'arbre, qui datacontext est le selectedValue à partir de la source.
L'Arborescence est un bien protégé appelé "ItemsHost", qui détient le TreeViewItem collection. Nous pouvons l'obtenir grâce à la réflexion et à pied de l'arbre à la recherche de l'élément sélectionné.
De cette façon, le comportement des œuvres pour des liaisons bidirectionnelles. Alternativement, il est possible de déplacer la ItemsHost l'acquisition du Comportement OnAttached méthode, en économisant les frais généraux de l'aide de la réflexion à chaque fois que la liaison des mises à jour.
WPF MVVM TreeView SelectedItem
... est une meilleure réponse, mais il ne mentionne pas un moyen d'obtenir/définir le SelectedItem dans le ViewModel.
Après des études à l'Internet pour une journée, j'ai trouvé ma solution pour la sélection d'un élément après avoir créer un normal treeview dans un normal WPF/C# environnement
Il peut aussi être fait en utilisant la propriété IsSelected de l'Arborescence de l'élément. Voici comment je l'ai réussi,
Puis dans le ViewModel qui contient les données de votre TreeView est lié à, il suffit de s'abonner à l'événement dans la TreeViewItem classe.
Et enfin, de mettre en œuvre ce gestionnaire dans le même ViewModel,
Et la liaison de cours,
Je vous apporte ma solution qui offre les fonctionnalités suivantes:
Prend en charge 2 façons de liaison
Automatique des mises à jour de la TreeViewItem.IsSelected propriétés (selon la SelectedItem)
Pas TreeView sous-classement
Éléments liés à ViewModel peut être de tout type (même nul)
1/Collez le code suivant dans votre CS:
2/Exemple d'utilisation dans votre fichier XAML
Je sais que ce fil est de 10 ans, mais le problème persiste....
La question d'origine était de "récupérer" l'élément sélectionné. J'ai aussi besoin de "récupérer" l'élément sélectionné dans mon viewmodel (pas). De toutes les réponses dans ce fil de discussion, l'un par 'Wes' est le seul qui aborde le problème différemment: Si vous pouvez utiliser l'Élément Sélectionné comme cible pour la liaison de données de l'utiliser comme source pour la liaison de données. Wes fait un autre point de vue de la propriété, je vais le faire à un viewmodel de la propriété:
Nous avons besoin de deux choses:
Viewmodel:
Vue constructeur:
(Disons simplement tous d'accord que le TreeView est évidemment éclaté à l'égard de ce problème. La liaison à SelectedItem aurait été évidente. Soupir)
J'avais besoin de la solution à interagir correctement avec l'IsSelected propriété de TreeViewItem, donc voici comment j'ai fait:
Avec ce code XAML: