Répondez avec des propriétés attachées et sans dépendances externes, si jamais le besoin s'en fait sentir !
Vous pouvez créer une propriété attachée qui peut être liée et qui possède un getter et un setter :
public class TreeViewHelper
{
private static Dictionary<DependencyObject, TreeViewSelectedItemBehavior> behaviors = new Dictionary<DependencyObject, TreeViewSelectedItemBehavior>();
public static object GetSelectedItem(DependencyObject obj)
{
return (object)obj.GetValue(SelectedItemProperty);
}
public static void SetSelectedItem(DependencyObject obj, object value)
{
obj.SetValue(SelectedItemProperty, value);
}
// Using a DependencyProperty as the backing store for SelectedItem. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.RegisterAttached("SelectedItem", typeof(object), typeof(TreeViewHelper), new UIPropertyMetadata(null, SelectedItemChanged));
private static void SelectedItemChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (!(obj is TreeView))
return;
if (!behaviors.ContainsKey(obj))
behaviors.Add(obj, new TreeViewSelectedItemBehavior(obj as TreeView));
TreeViewSelectedItemBehavior view = behaviors[obj];
view.ChangeSelectedItem(e.NewValue);
}
private class TreeViewSelectedItemBehavior
{
TreeView view;
public TreeViewSelectedItemBehavior(TreeView view)
{
this.view = view;
view.SelectedItemChanged += (sender, e) => SetSelectedItem(view, e.NewValue);
}
internal void ChangeSelectedItem(object p)
{
TreeViewItem item = (TreeViewItem)view.ItemContainerGenerator.ContainerFromItem(p);
item.IsSelected = true;
}
}
}
Ajoutez la déclaration d'espace de nom contenant cette classe à votre XAML et liez-la comme suit (local est le nom que j'ai donné à la déclaration d'espace de nom) :
<TreeView ItemsSource="{Binding Path=Root.Children}" local:TreeViewHelper.SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}">
</TreeView>
Vous pouvez maintenant lier l'élément sélectionné et le définir dans votre modèle de vue afin de le modifier de manière programmatique, si cela s'avère nécessaire. Cela suppose, bien sûr, que vous implémentez INotifyPropertyChanged sur cette propriété particulière.
57 votes
Mec, ça craint. Ça vient de me frapper aussi. Je suis venu ici en espérant trouver un moyen décent et je suis juste un idiot. C'est la première fois que je suis triste de ne pas être un idiot
9 votes
C'est vraiment nul et cela gâche le concept de liaison
0 votes
J'espère que cela pourra aider quelqu'un à se lier à un élément de l'arborescence sélectionné et à le rappeler sur une commande I. jacobaloysious.wordpress.com/2012/02/19/
9 votes
En termes de liaison et de MVVM, le code derrière n'est pas "interdit", mais le code derrière doit plutôt soutenir la vue. À mon avis, d'après toutes les autres solutions que j'ai vues, le code derrière est une bien meilleure option puisqu'il s'agit toujours de "lier" la vue au modèle de vue. Le seul point négatif est que si vous avez une équipe avec un designer travaillant uniquement en XAML, le code derrière peut être cassé ou négligé. C'est un petit prix à payer pour une solution qui prend 10 secondes à mettre en œuvre.
0 votes
C'est probablement l'une des solutions les plus simples : stackoverflow.com/questions/1238304/
0 votes
Le moyen le plus simple pour moi était este .
1 votes
Je pense qu'il est triste et étonnant que près d'une douzaine d'années plus tard, Microsoft n'ait toujours pas corrigé cette horrible expérience pour les développeurs. C'est... incroyable, vraiment.