WPF TreeView привязка данных, чтобы скрыть / показать развернуть / свернуть значок - PullRequest
4 голосов
/ 19 апреля 2010

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

Я хочу уточнить модель, добавив свойство public bool HasChildren { get { ... } } к моей основе TreeNodeViewModel.

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

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

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

Ответы [ 2 ]

2 голосов
/ 21 апреля 2010

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 значение False из кода, приведенного выше XAML:

xyz.HasChildren = false;

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

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

Петр.

1 голос
/ 19 апреля 2010

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

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

    _children = new ObservableCollection<TreeViewItemViewModel>();

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

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

...