仅限查看最后一项的Binded List Box

时间:2014-04-27 15:09:43

标签: c# wpf html-agility-pack observablecollection code-behind

我使用ObservableCollection将一些字符串绑定到列表框: 这是我的SongFinder代码:

     string title, downloadlink, artist, duration;
    private readonly HtmlWeb web = new HtmlWeb();
    public string Title
    {
        get { return title; }
        set { title = value; }
    }
    public string DownloadLink
    {
        get { return downloadlink; }
        set { downloadlink = value; }
    }
    public string Artist
    {
        get { return artist; }
        set { artist = value; }
    }
    public string Duration
    {
        get { return duration; }
        set { duration = value; }
    }

    public SongFinder(string pageuri)
    {

    }
    public void Mp3Monkey(string pageUri)
    {
        HtmlDocument doc = web.Load(pageUri);
        HtmlNode documentNode = doc.DocumentNode;
        doc.OptionUseIdAttribute = true;
        var xpath = "//div[@class='dd']/noindex/div";
        HtmlNodeCollection col = documentNode.SelectNodes(xpath);


        foreach (var n in col)
        {
            downloadlink = "https://www.mp3monkey.net/audio/" + n.SelectSingleNode("span[@id='oid']").InnerText + "/" + n.SelectSingleNode("span[@id='aid']").InnerText + "/" +
                        n.SelectSingleNode("span[@id='autor']").InnerText + "_-_" + n.SelectSingleNode("span[@id='title']").InnerText.Replace(" ", "_") + ".mp3";

            artist = n.SelectSingleNode("span[@id='autor']").InnerText;
            title = n.SelectSingleNode("span[@id='title']").InnerText;
            TimeSpan t = TimeSpan.FromSeconds(double.Parse(n.SelectSingleNode("span[@id='time']").InnerText));
            string answer = string.Format("{0:D2}:{1:D2}:{2:D2}",
             t.Hours,
             t.Minutes,
             t.Seconds);
            duration = answer;
        }
    }

以下是将可观察集合绑定到列表框的代码:

    <ListBox x:Name="list" ItemsSource="{Binding}" HorizontalAlignment="Left" Height="365" Margin="73,187,0,0" VerticalAlignment="Top" Width="460">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Title}"/>
                    <TextBlock Text="{Binding Artist}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

这是我的Code-Behind;

       this.DataContext = net;

        string Mp3Monkey1 = "Eminem Mp3 Download.htm";
        SongFinder find = new SongFinder(@"D:\books\" + Mp3Monkey1);
        find.Mp3Monkey(@"D:\books\" + Mp3Monkey1);
        net.Add(find);

现在我遇到的问题是,当加载所有信息时,ListBox只显示集合中的最后一首歌曲。请帮忙!! 如果我尝试调试没有绑定它工作正常并加载每首歌的所有信息。

为什么我想知道?

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:1)

在您的代码中,您会覆盖您的属性(艺术家,持续时间等等),所以显然您只会看到foreach循环处理过的最后一首歌。

<强>解决方案:

通过从Song

中的每个节点创建新的HTMLNodeCollection,使用您将填充循环的集合

示例:

代码

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;

namespace WpfApplication1
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            // Let's pretend this is your HtmlNodeCollection 
            var collection = new List<Song>
            {
                new Song
                {
                    Artist = "Joeski & Chus",
                    Title = "El Amor",
                    Duration = TimeSpan.FromMinutes(5).TotalSeconds
                },
                new Song
                {
                    Artist = "Dano & Joeski",
                    Title = "For your love",
                    Duration = TimeSpan.FromMinutes(10).TotalSeconds
                },
            };

            // Build objects from your HTML nodes ...
            var songs = new ObservableCollection<Song>();
            foreach (Song song in collection)
            {
                songs.Add(song);
            }

            DataContext = songs;
        }
    }

    internal class Song
    {
        public string Artist { get; set; }
        public string Title { get; set; }
        public double Duration { get; set; }
    }
}

XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfApplication1="clr-namespace:WpfApplication1"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Grid>
        <ListBox ItemsSource="{Binding}">
            <ListBox.ItemTemplate>
                <DataTemplate DataType="wpfApplication1:Song">
                    <Border Margin="2"
                            BorderBrush="Red"
                            BorderThickness="1">
                        <StackPanel>
                            <TextBlock Text="{Binding Artist, StringFormat='{}Artist: {0}'}" />
                            <TextBlock Text="{Binding Title, StringFormat='{}Title: {0}'}" />
                            <TextBlock Text="{Binding Duration, StringFormat='{}Duration: {0}'}" />
                        </StackPanel>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

结果

enter image description here

修改

代码示例:

var songs = new ObservableCollection<Song>();
foreach (var n in col)
{
    Song song = new Song();
    downloadlink = "https://www.mp3monkey.net/audio/" + n.SelectSingleNode("span[@id='oid']").InnerText + "/" + n.SelectSingleNode("span[@id='aid']").InnerText + "/" +
                n.SelectSingleNode("span[@id='autor']").InnerText + "_-_" + n.SelectSingleNode("span[@id='title']").InnerText.Replace(" ", "_") + ".mp3";

    song.Artist = n.SelectSingleNode("span[@id='autor']").InnerText;
    song.Title = n.SelectSingleNode("span[@id='title']").InnerText;
    // etc ...

    songs.Add(song);    
}

DataContext = songs;

确保您使用我的Song课程和ListBox以及我在XAML中定义的DataTemplate