Comment puis-je récupérer l'élément sélectionné dans une arborescence WPF? Je veux le faire en XAML, car je veux le lier.
Vous pourriez penser que c'est le cas SelectedItem
mais apparemment cela n'existe pas est en lecture seule et donc inutilisable.
Voici ce que je veux faire:
<TreeView ItemsSource="{Binding Path=Model.Clusters}"
ItemTemplate="{StaticResource ClusterTemplate}"
SelectedItem="{Binding Path=Model.SelectedCluster}" />
Je veux lier le SelectedItem
à une propriété de mon modèle.
Mais cela me donne l'erreur:
La propriété 'SelectedItem' est en lecture seule et ne peut pas être définie à partir du balisage.
Edit: Ok, c'est comme ça que j'ai résolu ceci:
<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;
}
Réponses:
Je me rends compte que la réponse a déjà été acceptée, mais je l'ai mise en place pour résoudre le problème. Il utilise une idée similaire à la solution de Delta, mais sans avoir besoin de sous-classer TreeView:
Vous pouvez ensuite l'utiliser dans votre XAML comme:
J'espère que cela aidera quelqu'un!
la source
{Binding SelectedItem, Mode=TwoWay}
par{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, vous ne pouvez donc pas l'affecter via une liaison, il suffit de le récupérer
la source
TreeView.SelectedItem
sur une propriété du modèle lorsque l'utilisateur sélectionne un élément (akaOneWayToSource
)?Répondez avec des propriétés attachées et sans dépendances externes, si le besoin se fait sentir!
Vous pouvez créer une propriété attachée qui peut être liée et possède un getter et un setter:
Ajoutez la déclaration d'espace de noms contenant cette classe à votre XAML et liez comme suit (local est la façon dont j'ai nommé la déclaration d'espace de noms):
Vous pouvez désormais lier l'élément sélectionné et le définir également dans votre modèle de vue pour le modifier par programme, si cette exigence devait se produire. Ceci, bien sûr, en supposant que vous implémentez INotifyPropertyChanged sur cette propriété particulière.
la source
Eh bien, j'ai trouvé une solution. Il déplace le désordre, de sorte que MVVM fonctionne.
Ajoutez d'abord cette classe:
et ajoutez ceci à votre xaml:
la source
Cela répond un peu plus que ce que le PO attend ... Mais j'espère que cela pourrait aider quelqu'un au moins.
Si vous souhaitez exécuter a
ICommand
chaque fois que vous leSelectedItem
modifiez, vous pouvez lier une commande à un événement et l'utilisation d'une propriétéSelectedItem
dans leViewModel
n'est plus nécessaire.Faire cela:
1- Ajouter une référence à
System.Windows.Interactivity
2- Lier la commande à l'événement
SelectedItemChanged
la source
System.Windows.Interactivity
peut être installée à partir de NuGet: nuget.org/packages/System.Windows.Interactivity.WPFSystem.Windows.Interactivity
. Cela a fonctionné pour moi (essayé avec le projet .NET Core). Pour configurer les choses, ajoutez simplement le package de nuget Microsoft.Xaml.Behaviors.Wpf , changez l'espace de noms enxmlns:i="http://schemas.microsoft.com/xaml/behaviors"
. Pour obtenir plus d'informations - veuillez consulter le blogCela peut être accompli d'une manière «plus agréable» en utilisant uniquement la liaison et EventToCommand de la bibliothèque GalaSoft MVVM Light. Dans votre machine virtuelle, ajoutez une commande qui sera appelée lorsque l'élément sélectionné est modifié et initialisez la commande pour effectuer toute action nécessaire. Dans cet exemple, j'ai utilisé un RelayCommand et je vais juste définir la propriété SelectedCluster.
Ajoutez ensuite le comportement EventToCommand dans votre xaml. C'est vraiment facile d'utiliser le mélange.
la source
Tout est compliqué ... Allez avec Caliburn Micro (http://caliburnmicro.codeplex.com/)
Vue:
ViewModel:
la source
Je suis tombé sur cette page à la recherche de la même réponse que l'auteur original, et prouvant qu'il y a toujours plus d'une façon de le faire, la solution pour moi était encore plus facile que les réponses fournies jusqu'ici, donc je me suis dit que je pourrais aussi bien ajouter à la pile.
La motivation pour la liaison est de la garder agréable et MVVM. L'utilisation probable du ViewModel est d'avoir une propriété avec un nom tel que "CurrentThingy", et ailleurs, le DataContext sur une autre chose est lié à "CurrentThingy".
Plutôt que de passer par des étapes supplémentaires nécessaires (par exemple: comportement personnalisé, contrôle tiers) pour prendre en charge une liaison agréable de TreeView à mon modèle, puis de quelque chose d'autre à mon modèle, ma solution consistait à utiliser un élément simple liant l'autre chose à TreeView.SelectedItem, plutôt que de lier l'autre chose à mon ViewModel, sautant ainsi le travail supplémentaire requis.
XAML:
Bien sûr, c'est idéal pour lire l'élément actuellement sélectionné, mais pas pour le définir, ce qui est tout ce dont j'avais besoin.
la source
Vous pouvez également utiliser la propriété TreeViewItem.IsSelected
la source
Il existe également un moyen de créer la propriété SelectedItem liable XAML sans utiliser Interaction.Behaviors.
Vous pouvez ensuite l'utiliser dans votre XAML comme:
la source
J'ai essayé toutes les solutions de ces questions. Personne n'a résolu mon problème complètement. Je pense donc qu'il est préférable d'utiliser une telle classe héritée avec la propriété redéfinie SelectedItem. Cela fonctionnera parfaitement si vous choisissez l'élément d'arbre dans l'interface graphique et si vous définissez cette valeur de propriété dans votre code
la source
J'avais besoin d'une solution basée sur PRISM-MVVM où un TreeView était nécessaire et l'objet lié est de type Collection <> et a donc besoin de HierarchicalDataTemplate. Le BindableSelectedItemBehavior par défaut ne pourra pas identifier le TreeViewItem enfant. Pour le faire fonctionner dans ce scénario.
Cela permet de parcourir tous les éléments quel que soit le niveau.
la source
Je suggère un ajout au comportement fourni par Steve Greatrex. Son comportement ne reflète pas les modifications de la source car il ne s'agit peut-être pas d'une collection de TreeViewItems. Il s'agit donc de trouver le TreeViewItem dans l'arborescence dont le datacontext est le selectedValue de la source. TreeView possède une propriété protégée appelée "ItemsHost", qui contient la collection TreeViewItem. Nous pouvons l'obtenir à travers la réflexion et marcher dans l'arbre à la recherche de l'élément sélectionné.
De cette façon, le comportement fonctionne pour les liaisons bidirectionnelles. Il est également possible de déplacer l'acquisition ItemsHost vers la méthode OnAttached du comportement, ce qui évite les frais généraux liés à l'utilisation de la réflexion à chaque mise à jour de la liaison.
la source
WPF MVVM TreeView SelectedItem
... est une meilleure réponse, mais ne mentionne pas un moyen d'obtenir / définir le SelectedItem dans le ViewModel.
la source
Après avoir étudié Internet pendant une journée, j'ai trouvé ma propre solution pour sélectionner un élément après avoir créé une arborescence normale dans un environnement WPF / C # normal
la source
Cela peut également être fait en utilisant la propriété IsSelected de l'élément TreeView. Voici comment je l'ai géré,
Ensuite, dans le ViewModel qui contient les données auxquelles votre TreeView est lié, abonnez-vous simplement à l'événement dans la classe TreeViewItem.
Et enfin, implémentez ce gestionnaire dans le même ViewModel,
Et la reliure bien sûr,
la source
Je sais que ce fil a 10 ans mais le problème existe toujours ....
La question d'origine était de «récupérer» l'élément sélectionné. J'avais également besoin de «récupérer» l'élément sélectionné dans mon modèle de vue (pas de le définir). De toutes les réponses de ce fil, celle de «Wes» est la seule qui aborde le problème différemment: si vous pouvez utiliser «l'élément sélectionné» comme cible pour la liaison de données, utilisez-le comme source pour la liaison de données. Wes l'a fait dans une autre propriété view, je vais le faire dans une propriété viewmodel:
Nous avons besoin de deux choses:
Viewmodel:
Constructeur de vue:
la source
(Soyons juste tous d'accord pour dire que TreeView est évidemment cassé en ce qui concerne ce problème. La liaison à SelectedItem aurait été évidente. Soupir )
J'avais besoin de la solution pour interagir correctement avec la propriété IsSelected de TreeViewItem, alors voici comment je l'ai fait:
Avec ce XAML:
la source
Je vous apporte ma solution qui offre les fonctionnalités suivantes:
Prend en charge la liaison 2 voies
Met à jour automatiquement les propriétés TreeViewItem.IsSelected (selon le SelectedItem)
Pas de sous-classement TreeView
Les éléments liés à ViewModel peuvent être de tout type (même nul)
1 / Collez le code suivant dans votre CS:
2 / Exemple d'utilisation dans votre fichier XAML
la source
Je propose cette solution (que je considère comme la plus simple et sans fuite de mémoire) qui fonctionne parfaitement pour mettre à jour l'élément sélectionné de ViewModel à partir de l'élément sélectionné de View.
Veuillez noter que la modification de l'élément sélectionné dans le ViewModel ne mettra pas à jour l'élément sélectionné de la vue.
Utilisation de XAML
la source