拖动MP3';s到C#中的ListView

本文关键字:中的 ListView MP3 拖动 | 更新日期: 2023-09-27 18:01:12

我目前正在开发自己的MP3播放器,希望添加拖放功能;可以拖放功能;一次放下一个文件或一次放下整个目录。我已经将ListView的View设置为详细信息,并且正在使用以下代码:

void Playlist_DragEnter(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
        e.Effect = DragDropEffects.Copy;  
}
void Playlist_DragDrop(object sender, DragEventArgs e)
{
    Playlist.Items.Clear();
    string[] songs = (string[])e.Data.GetData(DataFormats.FileDrop, false);
    Parallel.ForEach(songs, s =>
    {
        if (File.Exists(s))
        {
            if (string.Compare(Path.GetExtension(s), ".mp3", true) == 0)
            {
                MessageBox.Show(s);
                AddFileToListview(s);
            }
        }
        else if (Directory.Exists(s))
        {
            DirectoryInfo di = new DirectoryInfo(s);
            FileInfo[] files = di.GetFiles("*.mp3");
            foreach (FileInfo file in files)
            {
                AddFileToListview(file.FullName);
                MessageBox.Show(file.FullName);
            }
        }
    });
}
private void AddFileToListview(string fullFilePath)
{
    if (!File.Exists(fullFilePath))
        return;
    string song = Path.GetFileName(fullFilePath);
    string directory = Path.GetDirectoryName(fullFilePath);
    if (directory.EndsWith(Convert.ToString(Path.DirectorySeparatorChar)))
        directory = directory.Substring(0, directory.Length - 1); //hack off the trailing '
    ListViewItem itm = Playlist.Items.Add(song);
    itm.SubItems.Add(directory); //second column = path
}

我在那里有MessageBox,以确保我的代码被命中,tit总是向我显示正确的数据,但ListView中没有显示任何数据。你知道我做错了什么吗?

@ClearLogic:你说得对,我忘了在ListView中定义列,谢谢。现在我有另一个问题,我可以毫无问题地将多个目录拖动到ListView中,但当我尝试添加多个单个MP3时,我会在行上出现跨线程异常

 ListViewItem itm = Playlist.Items.Add(song);

拖动MP3';s到C#中的ListView

感谢@ClearLogic在解决此问题方面提供的所有帮助,我想我会分享我的代码,以防其他人也遇到一些问题。

private void Playlist_DragEnter(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
        e.Effect = DragDropEffects.Copy;  
}
private void Playlist_DragDrop(object sender, DragEventArgs e)
{
    //get the file names
    string[] songs = (string[])e.Data.GetData(DataFormats.FileDrop, false);
    //we're using a Parallel.ForEach loop because if a directory is selected it can contain n number of items, this is to help prevent a bottleneck.
    Parallel.ForEach(songs, song =>
    {
        //make sure the file exists
        if (File.Exists(song))
        {
            //if it's an mp3 file then call AddFileToListview
            if (string.Compare(Path.GetExtension(song), ".mp3", true) == 0)
            {
                AddFileToListview(song);
            }
        }
        //A HA! It's a directory not a single file
        else if (Directory.Exists(song))
        {
            //get the directory information
            DirectoryInfo di = new DirectoryInfo(song);
            //get all the mp3 files (will add WMA in the future)
            FileInfo[] files = di.GetFiles("*.mp3");
            //here we use a parallel loop to loop through every mp3 in the
            //directory provided
            Parallel.ForEach(files, file =>
            {
                AddFileToListview(file.FullName);
            });
        }
    });
}
private void AddFileToListview(string fullFilePath)
{
    double nanoseconds;
    string totalTime = string.Empty;
    //First things first, does the file even exist, if not then exit
    if (!File.Exists(fullFilePath))
        return;
    //get the song name
    string song = Path.GetFileName(fullFilePath);
    //get the directory
    string directory = Path.GetDirectoryName(fullFilePath);
    //hack off the trailing '
    if (directory.EndsWith(Convert.ToString(Path.DirectorySeparatorChar)))
        directory = directory.Substring(0, directory.Length - 1); 
    //now we use the WindowsAPICodePack.Shell to start calculating the songs time
    ShellFile shell = ShellFile.FromFilePath(fullFilePath);
    //get the length is nanoseconds
    double.TryParse(shell.Properties.System.Media.Duration.Value.ToString(), out nanoseconds);
    //first make sure we have a value greater than zero
    if (nanoseconds > 0)
    {
        // double milliseconds = nanoseconds * 0.000001;
        TimeSpan time = TimeSpan.FromSeconds(Utilities.ConvertToMilliseconds(nanoseconds) / 1000);
        totalTime = time.ToString(@"m':ss");
    }
    //build oour song data
    ListViewItem item = new ListViewItem();
    item.Text = song;
    item.SubItems.Add(totalTime);
    //now my first run at this gave me a cross-thread exception when trying to add multiple single mp3's
    //but I could add all the whole directories I wanted, o that is why we are now using BeginINvoke to access the ListView
    if (Playlist.InvokeRequired)
        Playlist.BeginInvoke(new MethodInvoker(() => Playlist.Items.Add(item)));
    else
        Playlist.Items.Add(item);            
}

此代码使用WindowsAPICodePack计算每首歌曲的时间。