Search code examples
c#wpflistboxmedia-player

Play multiple files in WPF listbox


This is how my music player looks like

Hello everyone, recently I'm doing a music player project on Visual Studio's WPF. After all of basic functionality has done, now I want to make a files playlist that contains multiple files.

So, when it runs, first I click on Open File button, to choose a file(s). Then, it will be loaded in the listbox. To play that song, I can choose either I double-clicked the song in the listbox or click the song after that I click the Play button. And the lblName info under "Now Playing" changed as my song selection changed.

I have tried to googling and code it (some copied and modified), and the files were loaded in my listbox, but it can't be played at all.

<Window x:Class="WPFplayer.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WPFplayer"
    mc:Ignorable="d"
    Title="WPF Music Player" Height="380.436" Width="507.483">
<Grid Margin="0,0,2,0" Height="350" VerticalAlignment="Top">
    <Grid.Background>
        <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0" SpreadMethod="Repeat">
            <GradientStop Color="Black" Offset="1"/>
            <GradientStop Color="#FFF3FF00" Offset="0.6"/>
        </LinearGradientBrush>
    </Grid.Background>
    <Button x:Name="btnOpen" Content="Open File..." HorizontalAlignment="Left" Margin="17,162,0,0" VerticalAlignment="Top" Width="75" Click="btnOpen_Click"/>
    <Button x:Name="btnPlay" Content="Play" HorizontalAlignment="Left" Margin="131,154,0,0" VerticalAlignment="Top" Width="75" Click="btnPlay_Click" Height="30"/>
    <Button x:Name="btnPause" Content="Pause" HorizontalAlignment="Left" Margin="211,154,0,0" VerticalAlignment="Top" Width="75" Click="btnPause_Click" Height="30"/>
    <Button x:Name="btnStop" Content="Stop" HorizontalAlignment="Left" Margin="291,154,0,0" VerticalAlignment="Top" Width="75" Click="btnStop_Click" Height="30"/>
    <Label x:Name="lblTime" Content="-----" HorizontalAlignment="Left" Margin="371,121,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.471,0.295"/>
    <Label x:Name="lblBiasa" Content="Now Playing :" HorizontalAlignment="Left" Margin="17,68,0,0" VerticalAlignment="Top" FontWeight="Bold"/>
    <Label x:Name="lblName" Content="(No Song...)" HorizontalAlignment="Left" Margin="17,94,0,0" VerticalAlignment="Top"/>
    <Slider x:Name="sliProgress" Thumb.DragStarted="sliProgress_DragStarted"  Thumb.DragCompleted="sliProgress_DragCompleted" ValueChanged="sliProgress_ValueChanged" HorizontalAlignment="Left" Margin="17,125,0,0" VerticalAlignment="Top" Width="354"/>
    <Slider x:Name="sliderVol" Value="0.5" Minimum="0" HorizontalAlignment="Left" Margin="436,92,0,0" VerticalAlignment="Top" Width="33" TickPlacement="BottomRight" Cursor="Arrow" Orientation="Vertical" Height="121" ValueChanged="sliderVol_ValueChanged" TickFrequency="0.1" SmallChange="0.01" LargeChange="0.1" Maximum="1"/>
    <Label x:Name="label" Content="MUSIC PLAYER" HorizontalAlignment="Left" Margin="173,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="22"/>
    <Label x:Name="label1" Content="Volume" HorizontalAlignment="Left" Margin="423,64,0,0" VerticalAlignment="Top" FontWeight="Bold"/>
    <CheckBox x:Name="chkKaraoke" Content="Karaoke" HorizontalAlignment="Left" Margin="286,78,0,0" VerticalAlignment="Top"/>
    <CheckBox x:Name="checkBox" Content="Bass Boost" HorizontalAlignment="Left" Margin="286,99,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.743,0.625"/>
    <ListBox x:Name="listBox" HorizontalAlignment="Left" Height="139" Margin="17,189,0,0" VerticalAlignment="Top" Width="388" SelectionChanged="listBox_SelectionChanged" MouseDoubleClick="listBox_MouseDoubleClick"/>
</Grid>

string[] files;

private void btnOpen_Click(object sender, RoutedEventArgs e)
{
  OpenFileDialog ofd = new OpenFileDialog();
  ofd.AddExtension = true;
  ofd.DefaultExt = "*.*";
  ofd.Filter = "All files (*.*)|*.*";
  ofd.Multiselect = true;
  ofd.ShowDialog();

  files = ofd.SafeFileNames;

  foreach (string song in files)
  {
    if (!listBox.Items.Contains(song))
    {
        listBox.Items.Add(song);
    }
  }

  foreach (var item in listBox.SelectedItems)
  {      
    lblName.Content = ofd.SafeFileName;
    mediaPlayer.Play();
  }

  DispatcherTimer timer = new DispatcherTimer();
  timer.Interval = new TimeSpan(0, 0, 1);
  timer.Tick += timer_Tick;
  timer.Start();
}

private void btnPlay_Click(object sender, RoutedEventArgs e)
{
  foreach (var item in listBox.SelectedItems)
  {       
    mediaPlayer.Play();
  }
}

private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
  lblName.Content = (listBox.SelectedValue).ToString();
}

private void listBox_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
  lblName.Content = (listBox.SelectedValue).ToString();    
  mediaPlayer.Play();
}

I wondering what things that I missed in that code. Should I add an event(s) to my listbox?

For your helps, I would like to say thank you.


Solution

  • Perhaps you forgot to post it. But it doesn't look like you are even telling the MediaPlayer what file to play. All you are doing is getting the song path, and telling the MediaPlayer to play -- without giving it what file to play.

    Assuming the list box item is the string of the song path, you would want this.

        mediaPlayer.Open(new Uri(item)); //item == song path(Including extension, i.e. .mp3)
        mediaPlayer.Play();
    

    However, it appears you are using .SafeFileName as well, which would make this problematic. So you may also want to do this if we are going to set the song directly from the listbox string.

    files = ofd.FileNames;