Saving listbox data with file paths C#

Hemanth B 886 Reputation points
2021-07-16T06:45:38.993+00:00

Hi, I created a media player in c#
Here is the code for Opening audio into a listbox:

private void OpenAudio()
        {

            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Multiselect = true;
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                axWindowsMediaPlayer1.Ctlcontrols.stop();
                file = ofd.SafeFileNames;
                paths = (paths ?? Enumerable.Empty<string>()).Concat(ofd.FileNames).ToArray();
                for (int i = 0; i < file.Length; i++)
                {
                    this.Width = 883;
                    listBox1.Items.Add(file[i]);

                }
            }
        }

Now I want to save the listbox items into a text file. I know how to do that:
Saving:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{

            using (TextWriter TW = new StreamWriter(@"C:\Users\bnara\Downloads\Mediasongs.txt"))
            {
                foreach (string itemtext in listBox1.Items)
                {
                    TW.WriteLine(itemtext);
                }
            }
}

Loading:

 var mediasongs = @"C:\Users\bnara\Downloads\Mediasongs.txt";
            using (StreamReader r = new StreamReader(mediasongs))
            {

                string line;
                while ((line = r.ReadLine()) != null)
                {
                    listBox1.Items.Add(line);

                }
            }

This code is saving and loading properly, but I want it the code to even save the file paths, because when the items get saved and then load and then when I try to play the loaded songs then this occurs: System.NullReferenceException: 'Object reference not set to an instance of an object.' that is because it is not saving the file paths. Please help!

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,307 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Anonymous
    2021-07-16T11:23:05.9+00:00

    Hello,

    Try looping through the paths instead, like this:

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
                     using (TextWriter TW = new StreamWriter(@"C:\Users\bnara\Downloads\Mediasongs.txt"))
                     {
                         foreach (string itemtext in paths)
                         {
                             TW.WriteLine(itemtext);
                         }
                     }
         }
    

  2. Karen Payne MVP 35,196 Reputation points
    2021-07-17T10:53:15.897+00:00

    Hello,

    A suggestion shown below, full source in this repository.

    • Note there is room for minor improvement
    • You need to alter the selection of the file from a static string to using an open dialog

    Create a class

    public class MediaItem  
    {  
        public string FileName { get; set; }  
        public override string ToString() => File.Exists(FileName) ? Path.GetFileName(FileName) : "";  
    }  
    

    Create code to save/load from a file

        /// <summary>  
        /// Load file names into a BindingSource which in turn becomes the DataSource for a ListBox  
        /// </summary>  
        /// <param name="sender"></param>  
        /// <returns></returns>  
        public static bool LoadFromFile(this BindingSource sender)  
        {  
            if (File.Exists(FileOperations.MediaFileName))  
            {  
                var lines = File.ReadAllLines(FileOperations.MediaFileName).Where(x => !string.IsNullOrWhiteSpace(x));  
                  
                sender.DataSource = (lines.Where(File.Exists).Select(line => new MediaItem() {FileName = line})).ToList();  
                return true;  
            }  
            else  
            {  
                return false;  
            }  
        }  
      
        /// <summary>  
        /// Save contents of ListBox to a file  
        /// </summary>  
        /// <param name="sender"></param>  
        /// <param name="FileName"></param>  
        public static void SaveToFile(this BindingSource sender, string FileName)  
        {  
            File.WriteAllLines(FileName, (from Row in sender.Cast<MediaItem>() select Row.FileName).ToArray());  
        }  
      
    }  
    

    A static class for file names, in a real app you would get the file name as currently doing. There are two properties, one for load one for save so you can test functionality then for real use use MediaFileName

    public class FileOperations  
    {  
        /// <summary>  
        /// For a real app this would no be hard coded  
        /// </summary>  
        public static string MediaFileName => "Mediasongs.txt";  
        /// <summary>  
        /// For a real app we save to <see cref="MediaFileName"/> but this helps  
        /// to ensure code is working correctly  
        /// </summary>  
        public static string SaveFileName => "MediasongsTest.txt";  
    }  
    

    Code to wrap MessageBox

    public static class Dialogs  
    {  
        public static bool Question(string text, string title = "Question") =>   
            (MessageBox.Show(text, title, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes);  
    }  
    

    Form code

    using System;  
    using System.Windows.Forms;  
    using MediaFileDemo.Classes;  
    using static MediaFileDemo.Classes.Dialogs;  
      
    namespace MediaFileDemo  
    {  
        public partial class Form1 : Form  
        {  
            private readonly BindingSource _bindingSource = new BindingSource();  
            public Form1()  
            {  
                InitializeComponent();  
                Shown += OnShown;  
      
            }  
      
            private void OnShown(object sender, EventArgs e)  
            {  
                _bindingSource.LoadFromFile();  
                listBox1.DataSource = _bindingSource;  
            }  
      
            private void GetFileNameButton_Click(object sender, EventArgs e)  
            {  
                if (listBox1.SelectedItem != null)  
                {  
                    MessageBox.Show(((MediaItem)listBox1.SelectedItem).FileName);  
                }  
                  
            }  
      
            private void SaveButton_Click(object sender, EventArgs e)  
            {  
                _bindingSource.SaveToFile("Test.txt");  
            }  
      
            private void DeleteCurrentButton_Click(object sender, EventArgs e)  
            {  
                if (listBox1.SelectedItem != null)  
                {  
                    if (Question("Delete"))  
                    {  
                        _bindingSource.Remove((MediaItem)listBox1.SelectedItem);  
                    }  
                }  
      
            }  
        }  
    }  
      
    

    I don't have any media files so I just used random files.

    115611-figure1.png

    0 comments No comments