【问题标题】:Populating wpf TreeView with specific XML structure使用特定的 XML 结构填充 wpf TreeView
【发布时间】:2019-01-30 17:45:09
【问题描述】:

我在 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作为一个节点,然后当我展开它时,有三个节点“Patient”,然后是Patient的相关内容。

相反,我得到了这个:

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;

【问题讨论】:

    标签: c# xml wpf treeview


    【解决方案1】:

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

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

    要为其他属性添加额外的节点,患者对象需要有一个对象集合(最好是 ObservableCollection)(可能只是字符串),这些对象可以是每个患者节点的 ItemSource。

    一般来说,TreeView 应该有一个顶级节点的 ItemSource(在您的示例中为 PatientLists),并且您为 Patient 定义了一个 HierarchicalDataTemplate,它有一个指向其子节点列表的 ItemSource。然后,您将为该列表中的每种类型的对象定义另一个 HierarchicalDataTemplate(或只是一个 DataTemplate)。

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

    【讨论】:

      【解决方案2】:

      您可以为 Tree 绑定 (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; }
      }
      

      TreeViewModel 类:

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

      【讨论】:

        猜你喜欢
        • 2013-08-25
        • 1970-01-01
        • 2017-05-25
        • 2017-06-05
        • 2011-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多