2010-04-19 5 views
4

Я реализовал дерево WPF по требованию, как описано в статье this (очень хорошо). В упомянутом решении фиктивный элемент используется для сохранения разворачивания поведения значка/дерева древа +. Фиктивный элемент заменяется реальными данными, когда пользователь нажимает на расширитель.WPF TreeView привязка данных для скрыть/показать значок расширения/свернуть

Я хочу улучшить эту модель, добавив недвижимость public bool HasChildren { get { ... } } на мою базу TreeNodeViewModel.

Вопрос:
Как я могу связать это свойство, чтобы скрыть/показать значок расширения (в XAML)? Я не могу найти подходящую комбинацию триггера/сеттера.
(INotifyPropertyChanged правильно реализована.)

Спасибо за ваше время.

Update 1:
Я хочу использовать свою собственность public bool HasChildrenвместо использования фиктивного элемента.
Определение того, имеет ли элемент детей несколько дорогостоящий, но все же намного дешевле, чем выбор детей.

ответ

2

Julian,

Это действительно хороший вопрос. Почему бы вам не попробовать написать свой собственный элемент дерева? :) Я имею в виду, не с нуля, просто получить из существующего TreeViewItem и добавить ваше свойство. Я подготовил быстрый образец, но не стесняйтесь изменять его по своему усмотрению (и задавать вопросы, если что-то не совсем ясно). здесь мы идем:

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); 
     } 

    } 
} 

Это код для вашего пользовательского TreeViewItem. Теперь давайте использовать его в 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> 

Как вы можете видеть, первый пункт является постоянным один и второй ваш заказ один. Обратите внимание, что у него есть один ребенок. Далее, вы можете связать HasChildren свойства некоторых булева объекта в вашем ViewModel или просто проверить свой собственный класс, установив HasChildren в ложных из кода за выше XAML:

xyz.HasChildren = false; 

Теперь, несмотря на ваш элемент имеет один ребенок, кнопка расширения не отображается, поэтому это означает, что мой пользовательский класс работает.

Надеюсь, я помог вам, но не стесняйтесь спрашивать, есть ли у вас какие-либо вопросы.

Piotr.

1

После быстро глядя в код Джоша, я нашел этот конструктор:

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

    _children = new ObservableCollection<TreeViewItemViewModel>(); 

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

Так что, если вы передаете false для параметра lazyLoadChildren из ваших наследуемых классов ViewModel, значок + не должен появиться, потому что DummyChild не добавлено. Поскольку вы, похоже, знаете, есть ли у ваших детей дети или нет, вы должны иметь возможность передать соответствующее значение для имущества lazyLoadChildren. Или я чего-то не хватает?