Filling the Songs ListBox

After the last post I saved some songs and built a list box to hold the song titles. I should say a little about that. These days I don’t write any SQL. I know that I still can write it because I wrote a simple SQL query for someone else a week or so ago. But I let someone else do it. By that I mean that I use an Object Relational Mapper. In my case I use LLBL Gen Pro. There are others out there but I have been using this for a few years now and I quite like it.

Some would suggest that using an O/RM is overkill for such a simple database schema. And it is. At this stage I don’t even know if I am going to use a database. But I have gotten so used to querying my databases through LLBL Gen that it is easier to just use it.

To get a collection of songs is pretty easy.

public EntityCollection GetAllSongs()
{
EntityCollection songs= new EntityCollection(new SongEntityFactory());
ExcludeFieldsList exFields = new ExcludeFieldsList();
exFields.Add(SongFields.Lyrics);
ISortExpression sorter = new SortExpression(SongFields.Title | SortOperator.Ascending);
using(DataAccessAdapter da = new DataAccessAdapter())
da.FetchEntityCollection(songs,null,0,sorter,null,exFields);
return songs;
}

This code is pretty straightforward. Line one creates a new collection of songs. The sorter says to sort on the Title field. LLBL Gen allows to different modes of data access: Adapter and Self-servicing. Adapter uses a DataAccessAdapter to fetch the entities. Self-servicing has a collection class for each type of entity and there are methods on the collection class to get the entities to fill the collection. This is simple enough to probably warrant using Self-Servicing, but again, I have been used to using Adapter, and so this is what I went with. It may change later, but that is not really an issue. At this stage I just want to be able to populate a list box.

The second line in the method is interesting. I said earlier that I am still uncertain if I will be using a database. But if I stick with it, I don’t know if I will populate the listbox with an entity collection. Performance wise it would probably make more sense to use a read only list. LLBL Gen will create TypedList classes for you, or you can generate your own dynamic list. But at the moment I just created a collection to see how it all hangs together. But doing this means pulling in a lot of data from the database that I don’t want. The database table for song has fields for Title, Author and Lyrics. The Title and Author are varchar(50) at the moment. That was the default size in SQLServer and it will do to start with. Lyrics, however, is much bigger. How big should it be? I don’t know yet, so I have set it to varchar(Max). The second line in the method says don’t get back the lyrics field. When I want to show the lyrics for a particular song I call another method to get the words.

So I saved a few songs and populated a listbox. Populating the listbox in WPF is pretty easy. I used a mixture of procedural code and xaml to accomplish it. My methods for accessing the database, that is, the code above, is held in a separate project called Tasks, for want of a better name. The songs listbox is held in a separate WPF control called SongListCtrl. To fill the listbox if use the following method

private void FillSongsListBox()
{
songs = tasks.GetAllSongs();
songsListBox.ItemsSource = songs;
}

The ItemsSource property binds the songs collection to the songsListBox. In the Xaml code I set the DisplayMemberPath to Title and that is what is shown in the listbox.

Now comes the hard part. I have a list of songs and I need to display the words. The first thing is to go back to database and get the Lyrics for that song, as explained earlier. I also created a new class SongSelectionEventArgs, which derives from EventArgs and has a property, SongEntity. The EventHandler is done with the standard generic event declaration

public static event EventHandler SelectSong;

public static void OnSelectSong(object sender, SongSelectionEventArgs e)
{
if (SelectSong != null)
SelectSong(sender, e);
}

Now the window that contains the SongListCtrl can listen to changes in the listbox selection. This is all pretty standard stuff. In WPF it works exactly the same way as in winforms. Although there are other ways to handle behaviour, for example using commands as I mentioned in the last post.

It is now time to show the songs on the monitor, and on a separate monitor, which in production will be a projector. This was a major problem as we will see in the next post.