Создание иерархии дерева в 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" />