简体   繁体   English

通过绑定创建TreeView(子节点作为列表) <MyType> )在MVVM中

[英]Create TreeView from binding (child node as List<MyType>) in MVVM

I need my TreeView to display playlists and their songs, it should look something like this: 我需要TreeView来显示播放列表及其歌曲,它看起来应该像这样:

-Playlist1
--Song1
--Song2
--Song3
-Playlist2
--Song1
--Song2
--Song3
--Song4
-Playlist3
--Song1
--Song2

There can be an unlimited amount of playlists in the TreeView , with each node having differing amounts of songs. TreeView可以有无限数量的播放列表,每个节点具有不同数量的歌曲。 I want to achieve this using MVVM. 我想使用MVVM实现此目的。

MainWindow.xaml MainWindow.xaml

<TreeView ItemsSource="{Binding PlayLists}">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type types:Playlist}" ItemsSource="{Binding PlayLists}">
            <TextBlock Text="{Binding Path=Name}"/>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="{x:Type types:Song}">
            <TextBlock Text="{Binding Path=Title}"/>
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

Playlist.cs 播放清单

public class Playlist
{
    public string Name { get; set; }
    public List<Song> Songs { get; set; }

    public static ObservableCollection<Playlist> Playlists { get; set; } = new ObservableCollection<Playlist>();
}

Song.cs Song.cs

public class Song
{
    public string FullPath { get; set; }
    public string Title { get; set; }
    public string Artist { get; set; }
    public string Genre { get; set; }
    public string Length { get; set; }
    public string Size { get; set; }
}

MainViewModel.cs MainViewModel.cs

public ObservableCollection<Playlist> PlayLists { get; set; }

public MainViewModel()
{

    /* Get Play-lists */
    string listsPath = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "AppName",  "Playlists");
    if (!Directory.Exists(listsPath))
    {
        Directory.CreateDirectory(listsPath);
    }

    string[] playlists = Directory.GetDirectories(listsPath);

    foreach (var playlist in playlists)
    {
        var songs = new List<Song>();
        string[] songsInPath = Directory.GetFiles(playlist);
        foreach (var song in songsInPath)
        {
            songs.Add(NewSong(song));
        }

        Playlist newPlaylist = new Playlist()
        {
            Name = playlist.Split(Path.DirectorySeparatorChar).Last(),
            Songs = songs
        };

        Playlist.Playlists.Add(newPlaylist);
    }
    PlayLists = Playlist.Playlists;
}

This is what it looks like: 看起来是这样的:

在此处输入图片说明

There should be a sub-nodes for every song in the playlist. 播放列表中的每首歌曲都应该有一个子节点。

The TreeView only shows the Playlist 's Name , but not the Song 's Title . TreeView仅显示PlaylistName ,而不显示SongTitle I realized this is because the Playlist 's property Songs is actually a List<Song> . 我意识到这是因为Playlist的属性Songs实际上是List<Song> I am not sure how I can display each Song 's Title from the property Playlist.Songs . 我不确定如何从属性Playlist.Songs显示每首Song的标题。

Can someone please help me with this. 有人可以帮我吗

Your structure for Songs is wrong 您的Songs结构错误

Have a look at this example: 看一下这个例子:

<HierarchicalDataTemplate DataType="{x:Type self:Family}" ItemsSource="{Binding Members}">
    <StackPanel Orientation="Horizontal">
        <Image Source="/WpfTutorialSamples;component/Images/group.png" Margin="0,0,5,0" />
        <TextBlock Text="{Binding Name}" />
        <TextBlock Text=" [" Foreground="Blue" />
        <TextBlock Text="{Binding Members.Count}" Foreground="Blue" />
        <TextBlock Text="]" Foreground="Blue" />
    </StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type self:FamilyMember}">
    <StackPanel Orientation="Horizontal">
        <Image Source="/WpfTutorialSamples;component/Images/user.png" Margin="0,0,5,0" />
        <TextBlock Text="{Binding Name}" />
        <TextBlock Text=" (" Foreground="Green" />
        <TextBlock Text="{Binding Age}" Foreground="Green" />
        <TextBlock Text=" years)" Foreground="Green" />
    </StackPanel>
</DataTemplate>

Given this Model 给定此模型

public class Family
{
    public Family()
    {
        this.Members = new ObservableCollection<FamilyMember>();
    }

    public string Name { get; set; }

    public ObservableCollection<FamilyMember> Members { get; set; }
}

public class FamilyMember
{
    public string Name { get; set; }

    public int Age { get; set; }
}

Take a look at this for reference: 看一下这个作为参考:

TreeView, data binding and multiple templates TreeView,数据绑定和多个模板

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM