将可观察集合绑定到 WPF 中的 TreeView

Binding observable collection to a TreeView in WPF

提前致谢,

我想将一个可观察集合绑定到 WPF 中的 TreeView,这样它应该将每个 TreeView 节点显示为 CountryType。 TreeView 从后面的代码绑定到此集合。

代码如下:

public partial class MyUserControl: UserControl
{
    public ObservableCollection<Person> myList { get; set; }

    public IEnumerable<PersonViewModel> PersonViewModelList { get; set; }

     public MyUserControl()
     {
       InitializeComponent();
       PopulateCollection();
       DataContext = this;
     }

     private void PopulateCollection()
        {
            myList = new ObservableCollection<Person>()
            {
                new Person{ Name="Name 1", Age=21, CountryType = CountryList.India},
                new Person{ Name="Name 2", Age=21, CountryType = CountryList.US},
                new Person{ Name="Name 3", Age=24, CountryType = CountryList.Israel},
                new Person{ Name="Name 4", Age=24, CountryType = CountryList.Israel},
                new Person{ Name="Name 5", Age=24, CountryType = CountryList.Russia},
                new Person{ Name="Name 6", Age=24, CountryType = CountryList.India},
                new Person{ Name="Name 7", Age=24, CountryType = CountryList.Russia},
                new Person{ Name="Name 8", Age=24, CountryType = CountryList.Russia},
                new Person{ Name="Name 9", Age=24, CountryType = CountryList.Japan},
                new Person{ Name="Name 10", Age=24, CountryType = CountryList.Japan},
                new Person{ Name="Name 11", Age=24, CountryType = CountryList.India},
                new Person{ Name="Name 12", Age=24, CountryType = CountryList.India},
            };

            PersonViewModelList = myList.GroupBy(x => x.CountryType)
            .Select(g => new PersonViewModel()
            {
                CountryType = g.Key,
                Names = g.Select(x => x.Name).OrderBy(n => n).ToList()
            });          
        }
  }

  public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public CountryList CountryType { get; set; }        
    }

    public class PersonViewModel
    {
        public CountryList CountryType { get; set; }
        public List<string> Names { get; set; }
    }

  public enum CountryList
    {
        India,
        Russia,
        US,
        Israel,
        Japan
    }

用户控件(XAML 文件)

 <TreeView ItemsSource="{Binding PersonViewModelList}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Path=Names}" DataType="{x:Type local:PersonViewModel}">
                <HierarchicalDataTemplate.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=CountryType}"></TextBlock>
                    </DataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

预期:

我不太确定我应该在 TreeView 中进行哪些更改才能使其正常工作。 再次感谢。

您当前的 Person 类型不适合或无法满足您的要求。您需要将数据转换为分层视图模型:

public class PersonViewModel
{
    public CountryList CountryType { get; set; }
    public List<string> Names { get; set; }
}

只需将您当前的 myListCountryType 分组并绑定到结果:

var transformedList = myList
    .GroupBy(x => x.CountryType)
    .Select(g => new PersonViewModel()
    { 
        CountryType = g.Key, 
        Names = g.Select(x => x.Name).OrderBy(n => n).ToList() 
    });

XAML:

<TreeView ItemsSource="{Binding PersonViewModelList}">
    <TreeView.Resources>
        <HierarchicalDataTemplate ItemsSource="{Binding Names}" DataType="{x:Type local:PersonViewModel}">
            <TextBlock Text="{Binding CountryType}" />
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

你需要反转你的数据结构,像这样...

var countyPeople = MyList.GroupBy(p => p.CountryType)
    .Select(g => new {Country = g.Key, People = g.ToList()})
    .OrderBy(c => c.Country)
    .ToList();

然后您可以将其设置为 TreeView 的 ItemsSource。

您的 HierarchicalDataTemplate 中的 ItemsSource 然后将绑定到此匿名类型的人员 属性。