Создание иерархии дерева в xaml

Это кажется обычным вопросом, но я не смог заставить его работать на основе ответов на другие вопросы.

У меня есть компания, у которой есть несколько проектов, и у каждого проекта может быть несколько задач. Класс компании содержит некоторые метаданные, а также список принадлежащих ему проектов, класс проекта также содержит некоторые метаданные и список задач, которые у него есть. Я пытаюсь отобразить эту иерархию в виде дерева. Я сделал образец объекта компании, у которой есть 2 проекта, а у проекта 1 есть 2 задачи. Древовидное представление должно отображать только одну компанию за раз, поэтому корневыми древовидными элементами являются проекты.

Вот моя попытка решить проблему, но ничего не отображается.

<TreeView ItemsSource="{Binding listOfProjects}" Margin="10" Height="200">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding listOfTasks}" DataType="{x:Type local:Task}">
            <TreeViewItem Header="{Binding name}"/>
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <TreeViewItem Header="{Binding name}" />
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

Как мне сделать это правильно? Что я должен связать с ItemsSource? Для заголовков TreeViewItem, как мне сообщить ему, какое поле связать? На данный момент у меня есть {Binding name}, но как мне отличить, откуда оно берется (потому что у проекта есть поле 'name', и у него тоже есть задача).

Я буду расширять иерархию дальше (задача может состоять из нескольких частей и т. Д.), Но я предполагаю, что каждый дополнительный уровень будет выполняться так же, как и первые 2.

редактировать: здесь моя компания, проект и классы задач.

class Company
{
    public List<Project> listOfProjects;
    public string name { get; set; }
    private int companyID { get; set; }

    public Company()
    {
        companyID = 0;
        name = "Default";
        listOfProjects = new List<Project>();
    }

    public Company(string inName)
    {
        companyID = 0;
        name = inName;
        listOfProjects = new List<Project>();
    }
} 
class Project
{
    private int projID { get; set; }
    public string name { get; set; }
    public DateTime startDate { get; set; }
    public DateTime endDate { get; set; }
    public string region { get; set; }
    private int companyID { get; set; }
    public List<Task> listOfTasks;

    public Project()
    {
        projID = 0;
        name = "Default";
        startDate = new DateTime();
        endDate = new DateTime();
        region = "Default";
        companyID = 0;
        listOfTasks = new List<Task>();
    }

    public Project(string inName)
    {
        projID = 0;
        name = inName;
        startDate = new DateTime();
        endDate = new DateTime();
        region = "Default";
        companyID = 0;
        listOfTasks = new List<Task>();
    }
}

В задачах atm нет ничего, кроме конструктора. Имеет 2 поля, идентификатор проекта и имя.

2 ответа

Решение

Ваш иерархический шаблон данных переопределяет ваше древовидное представление. Вы должны переименовать listofProject а также listofTask с таким же именем. Поэтому вы создаете интерфейс или класс. Затем реализуете Company,Project,Task из этого интерфейса.

public interface ITreeItem
    {
        string Name { get; }
        List<ITreeItem> childs { get; }
    }


    public class Company : ITreeItem
    {

        public string Name
        {
            get { return name; }
        }

        public List<ITreeItem> childs
        {
            get { return listofProjects; }
        }
    }

    public class Project : ITreeItem
    {
        public string Name
        {
            get { return name; }
        }

        public List<ITreeItem> childs
        {
            get { return listofTask; }
        }
    }

    public class Task : ITreeItem
    {
        public string Name
        {
            get { return name; }
        }

public List<ITreeItem> childs
        {
            get { return null; }
        }
    }

Тогда ваш шаблон

<HierarchicalDataTemplate ItemsSource="{Binding childs}" DataType="{x:Type local:ITreeItem}">
            <TreeViewItem Header="{Binding Name}"/>
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <TreeViewItem Header="{Binding Name}" />
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>

Таким образом, все верхние уровни будут иметь тип "проект", а все ветви будут иметь тип "задача"? Вы можете использовать несколько HierarchicalDataTemplates следующим образом:

<StackPanel.Resources>
    <sdk:HierarchicalDataTemplate x:Key="TaskTemplate" 
        ItemsSource="{Binding Path=Childs}"> 
       <TextBlock FontStyle="Italic" Text="{Binding Path=Name}" />
     </sdk:HierarchicalDataTemplate>
    <sdk:HierarchicalDataTemplate x:Key="ProjectTemplate" 
        ItemsSource="{Binding Path=ListOfTasks}" 
        ItemTemplate="{StaticResource TaskTemplate}">
        <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" />
        </sdk:HierarchicalDataTemplate>
</StackPanel.Resources>

А затем объявите ваше дерево как это...

<sdk:TreeView ItemsSource="{Binding MyProjectList}" 
    ItemTemplate="{StaticResource ProjectTemplate}" x:Name="myTreeView" />
Другие вопросы по тегам