使用特定的 XML 结构填充 wpf 树视图



我在StackOverflow周围搜索,但似乎找不到答案。我是 WPF 的新手,我真的对 xaml 部分感到困惑。那么如何从下面制作一个像xml这样的结构呢?

我正在尝试为这个 xml 构建一个视图:

<?xml version="1.0" encoding="utf-8"?>
<Patients>
<Patient>
<ID>44</ID>
<Name>Ben Garsia</Name>
<Year>1985</Year>
</Patient>
<Patient>
<ID>22</ID>
<Name>Melisa Mayer</Name>
<Year>1968</Year>
</Patient>
<Patient>
<ID>33</ID>
<Name>Morgan Smith</Name>
<Year>1979</Year>
</Patient>
</Patients>

并希望 Treeview 完全像这样,所以首先将患者作为节点,然后当我扩展它时,有三个节点"患者",然后是患者相关的东西。

相反,我得到这个:

Patients
44Ben Garsia1985
22Melisa Mayer1968
33Morgan Smith1979

这是我的 xaml:

<Window x:Class="LoadTreeView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LoadTreeView"
Title="MainWindow" Height="450" Width="800">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TreeView Name="treeViewT">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:PatientsList}" ItemsSource="{Binding Patients}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Patients" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:Patient}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ID}" />
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Year}" />
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
<StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Center">
<Button x:Name="btnLoad" Content="Load file" Width="100" Click="button_Click"  
HorizontalAlignment="Left" Margin="4" VerticalAlignment="Top"/>
</StackPanel>
</Grid>

我用过的类:

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public class Patient
{
public int ID { get; set; }
public string Name { get; set; }
public int Year { get; set; }
}
[XmlRootAttribute("Patients")]
public class PatientsList
{
[XmlElement("Patient")]
public Patient[] Patients { get; set; }
}

在 xaml 的代码后面,我像这样填充它:

var patientsList = new List<PatientsList>();
patientsList.Add(patients);
treeViewT.ItemsSource = patientsList;

您将患者的 DataTemplate 定义为具有三个 TextBlock 的堆栈面板,因此这就是树中每个节点所显示的内容。

相反,DataTemplate 应该只是您希望节点显示的内容,可能只是名称的单个文本块,可能带有图标。

若要为其他属性添加额外的节点,患者对象需要具有对象(可能只是字符串(的集合(理想情况下是 ObservableCollection(,这些对象可以是每个患者节点的 ItemSource。

通常,TreeView 应具有顶级节点的 ItemSource(在您的示例中为 PatientLists(,并且您为患者定义一个 HierarchicalDataTemplate,该模板将具有指向其子节点列表的 ItemSource。然后,您将为该列表中的每种类型的对象定义另一个 HierarchicalDataTemplate(或只是一个 DataTemplate(。

在您的情况下,您可能需要一个 PatientViewModel,它将为其属性公开字符串的 ObservableList。

可以为树绑定 (TreeViewModel( 创建单独的类。 下面是与 XML 完全相同的树的代码。

XAML:

<TreeView Name="treeViewT" ItemsSource="{Binding Tree}" >
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:TreeViewModel}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Title}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>

视图模型:

public class ViewModel 
{
public ViewModel()
{
Tree = new ObservableCollection<TreeViewModel>();
LoadData();
}
private void LoadData()
{
var list1 = new PatientsList();
list1.Patients.Add(new Patient { ID = 44, Name = "Ben Garsia", Year = 1985 });
list1.Patients.Add(new Patient { ID = 22, Name = "Melisa Mayer", Year = 1968 });
list1.Patients.Add(new Patient { ID = 33, Name = "Morgan Smith", Year = 1979 });
var root = new TreeViewModel();
root.Add(list1);
Tree.Add(root);
}
public ObservableCollection<TreeViewModel> Tree { get; set; }
}

树视图模型类:

public class TreeViewModel
{
public TreeViewModel()
{
Children = new ObservableCollection<TreeViewModel>();
Title = "Patients"; // Root node name
}
public string Title { get; private set; }
public ObservableCollection<TreeViewModel> Children { get; }
public void Add(PatientsList list)
{
foreach (var i in list.Patients)
{
var child = new TreeViewModel();
child.Title = "Patient"; // Level2 node name
child.Add(i);
Children.Add(child);
}
}
private void Add(Patient patient)
{
Add($"ID: {patient.ID}");
Add($"Name: {patient.Name}");
Add($"Year: {patient.Year}");
}
private void Add(string title)
{
Children.Add(new TreeViewModel { Title = title });
}
}

最新更新