Part 15: Playing a Sound when a ListItem is Selected
Now that we have our data model loaded with live data, not the least of which is the path to the sound files, actually PLAYING those sounds is relatively easy.
Our game plan:
- We'll add a MediaElement control to the page ... we'll not set the Source declaratively, rather we'll set it programmatically
- We'll wire up an event handler that will be triggered each time the user taps a different tile
- In the body of that event handler method, we'll set the Source property of the MediaElement control
1. Add a MediaElement to the MainPage.xaml
Since we need the MediaElement on each PivotItem, I'll add the control near the top of the code, beneath the LayoutRoot Grid control:
Notice in line 42 I give the MediaElement a name because I plan on accessing it programmatically in C#, and I set the Volume to 1, the loudest setting possible.
2. Handle the LongListSelector_SelectionChanged event
Next, I add an attribute to the LongListSelector that will be triggered each time a tile is tapped. I use the technique I demonstrated in an earlier video to allow Visual Studio to create the event handler method's name and create the event handler method stub. (Hint: type SelectionChanged=" and when the contextual dialog appears select the Enter key to auto implement the rest of the code). It should look like this (see line 51):
Navigate to the event handler method in the code behind and implement the code to play the sound associated with the tile:
- Here we get a reference to the LongListSelector. Since we have five LongListSelectors defined on our page (because we have five references to the DataTemplate in the Page's Resources) we need to access the one that the user clicked on (or more correctly, find the LongListSelector whose list item was clicked on). Notice the "as LongListSelector" on the end of that line. This is a form of data type conversion ... sender is object, but we know it must be a LongListSelector. the "as" keyword used here will convert sender to the type LongListSelector.
- We want to ensure that the selector is not null. While not probable, it is entirely possible for something to have gone awry and some other type was passed in as sender. We're guarding ourselves against that possibly by programming defensively here.
- Likewise, we want to access the list item that was selected, so we access the selector's SelectItem and attempt to convert that into an object of type SoundData
- Again, we want to ensure that the data object is not null. While not probably, it's possible for something to have gone awry and some other type was retrieved via the SelectedItem property. By checking for null we're guarding ourselves against this possibility by programming defensively
- Now that we have the SoundData that was selected, we set the Source property of the MediaElement.
Let's run to test the app:
This seems to work fine at first, but after repeated testing I realize we have a problem. If we tap the same tile twice, I don't get a sound. That's because the selection didn't change and therefore our event handler is not triggered.
3. Fixing select selection problem
To fix this, we need to reset the SelectedItem to null after we've finished playing the sound:
Re-running and testing the app proves our solution to have worked.
To recap, the big take away was how to programmatically work with the MediaPlayer element by setting the Source property to dynamically change the sound that is played. We learned about the "as" keyword which performs conversions on compatible reference types. In our case, we needed to cast the input property "object sender" to the LongListSelector and the SelectedItem to SoundData, the type our DataTemplate was bound to. And finally we learned how to unselect a selected item in a LongListSelector by setting the SelectedItem property to null.