2010-04-19 13 views
4

J'ai implémenté une arborescence de chargement à la demande WPF comme décrit dans l'article this (très bon). Dans la solution mentionnée, un élément fictif est utilisé pour préserver le comportement d'expansion + icon/treeview. L'élément factice est remplacé par des données réelles lorsque l'utilisateur clique sur l'extension.Liaison de données WPF TreeView pour masquer/afficher développer/réduire l'icône

Je veux affiner le modèle en ajoutant une propriété public bool HasChildren { get { ... } } à mon support TreeNodeViewModel.

Question:
Comment puis-je lier cette propriété de masquer/afficher l'icône de développement (en XAML)? Je ne suis pas en mesure de trouver une combinaison déclencheur/setter appropriée.
(INotifyPropertyChanged est correctement implémenté.)

Merci de votre temps.

Mise à jour 1:
Je veux utiliser ma propriété public bool HasChildrenau lieu d'utiliser l'élément factice.
Déterminer si un article a des enfants est un peu coûteux, mais toujours beaucoup moins cher que d'aller chercher les enfants.

Répondre

2

Julian,

Ceci est une très bonne question. Pourquoi n'essayez-vous pas d'écrire votre propre élément de vue arborescente? :) Je veux dire, pas du tout, dérivez juste de TreeViewItem existant et ajoutez votre propriété. J'ai préparé un échantillon rapide, mais n'hésitez pas à le modifier comme vous le souhaitez (et posez des questions si quelque chose n'est pas parfaitement clair). on y va:

public class TreeViewItem_CustomControl : TreeViewItem 
{ 
    static TreeViewItem_CustomControl() 
    { 
     HasChildrenProperty = DependencyProperty.Register("HasChildren", typeof(Boolean), typeof(TreeViewItem_CustomControl)); 
    } 

    static DependencyProperty HasChildrenProperty; 

    public Boolean HasChildren 
    { 
     get 
     { 
      return (Boolean)base.GetValue(HasChildrenProperty); 
     } 

     set 
     { 
      if (value) 
      { 
       if (this.Items != null) 
       { 
        this.Items.Add(String.Empty); //Dummy item 
       } 
      } 
      else 
      { 
       if (this.Items != null) 
       { 
        this.Items.Clear(); 
       } 
      } 

      base.SetValue(HasChildrenProperty, value); 
     } 

    } 
} 

Ceci était le code pour votre TreeViewItem personnalisé. Maintenant, nous allons l'utiliser en XAML:

<TreeView> 
    <TreeViewItem Header="qwer"> 
     Regulat tree view item. 
    </TreeViewItem> 
    <CustomTree:TreeViewItem_CustomControl x:Name="xyz" Header="temp header" Height="50"> 
     <TreeViewItem>Custom tree view item, which will be removed.</TreeViewItem> 
    </CustomTree:TreeViewItem_CustomControl> 
</TreeView> 

Comme vous pouvez le voir, le premier élément est un régulier et le second est votre commande un. S'il vous plaît noter qu'il a un enfant. Ensuite, vous pouvez lier HasChildren propriété à un objet Boolean dans votre ViewModel ou tout simplement tester ma classe personnalisée en mettant HasChildren à Faux à partir du code derrière le XAML ci-dessus:

xyz.HasChildren = false; 

Maintenant, en dépit de votre élément a un enfant, le bouton d'expansion n'est pas affiché, donc cela signifie que ma classe personnalisée fonctionne.

J'espère que je vous ai aidé, mais n'hésitez pas à demander si vous avez des questions.

Piotr.

1

Après avoir regardé rapidement dans le code de Josh, j'ai trouvé ce constructeur:

protected TreeViewItemViewModel(TreeViewItemViewModel parent, bool lazyLoadChildren) 
{ 
    _parent = parent; 

    _children = new ObservableCollection<TreeViewItemViewModel>(); 

    if (lazyLoadChildren) 
     _children.Add(DummyChild); 
} 

Donc, si vous passez false pour le paramètre lazyLoadChildren de vos héritant des classes ViewModel, l'icône + ne doit pas apparaître parce que le DummyChild n'est pas ajoutée. Puisque vous semblez savoir si vos articles ont des enfants ou pas, vous devriez pouvoir passer la valeur appropriée pour la propriété lazyLoadChildren. Ou est-ce que je manque quelque chose?