Search code examples
c#listviewuwpmediaelement

play music when listview item is selected


I am developing a music app. I have used the listview to add music files into it but when I click on listview item to play music it throws exception that The URI is empty. Any help regarding this.

Here is my code

.XAML

<MediaElement x:Name="mediaElement" AreTransportControlsEnabled="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <MediaElement.TransportControls>
            <MediaTransportControls IsZoomEnabled="False" IsZoomButtonVisible='False' IsSeekBarVisible="True" IsSeekEnabled="True" IsFullWindowButtonVisible="False" IsStopButtonVisible="True"/>
        </MediaElement.TransportControls>
    </MediaElement>
    <ListView x:Name="listView" Margin="0,0,0,115" ItemClick="itemclicked" IsItemClickEnabled="True">
    </ListView>

.cs

 public MainPage()
    {
        this.InitializeComponent();

        files();
    }
    private async void files()
    {
        var query = KnownFolders.MusicLibrary.CreateFileQuery();
        var allFiles = await query.GetFilesAsync();
        foreach (var f in allFiles)
        {
            listView.Items.Add(f.DisplayName.ToString());

        }
    private void itemclicked(object sender, ItemClickEventArgs e)
    {

        mediaElement.Source = new Uri(listView.SelectedValuePath);
    }

Solution

  • It's because you are doing it all wrong.

    Your list contains only strings that are DisplayNames of the files.

    the simplest example might be:

    private async void files()
    {
        var query = KnownFolders.MusicLibrary.CreateFileQuery();
        var allFiles = await query.GetFilesAsync();
    
        foreach (var f in allFiles)
        {
            listView.Items.Add(f);
        }
    }
    

    so you will have files, not names loaded into your list

    and then you need to get clicked file and set it as source:

    private async void itemclicked(object sender, ItemClickEventArgs e)
    {
        var file = e.ClickedItem as StorageFile;
        if(file != null)
        {
            var stream = await file.OpenReadAsync();
            mediaElement.SetSource(stream, file.ContentType);
        }
    }
    

    to have the list control displaying file names you might add item template, like that:

    <Page.Resources>
        <DataTemplate x:Key="NewItemTemplate">
            <TextBlock Text="{Binding DisplayName}"></TextBlock>
        </DataTemplate>
    </Page.Resources>
    
    <ListView x:Name="listView" Margin="0,0,0,115" ItemClick="itemclicked" IsItemClickEnabled="True" ItemTemplate="{StaticResource NewItemTemplate}">
        </ListView>
    

    it will work, but of course I would rather think about creating some custom items that will keep references to files and keep them in ObservableList binded to ItemsSource of the list and so on, rather that putting raw files into the list