Creating the list of songs was fairly straightforward. Now I need to show the words on the screen. I said in the previous post that I raised an event when the songslist selection changed. In the window, actually another control, I add a handler to listen to the event. Actually, Visual Studio does most of it for you if you press Tab a few times. After the mandatory InitialzeComponent is called in the control’s constructor I have this line of code:
EventHub.SelectSong += new EventHandler
EventHub is the class that contains my event declarations. Within Visual studio you just type
and hit the Tab key twice. VS completes the line and creates a method for you. You just fill in the code in the method.
EventHub.SelectSong +=
void EventHub_SelectSong(object sender, SongSelectionEventArgs e)
{
song= tasks.GetSongLyrics(e.Song);
XmlTextReader reader = new XmlTextReader(new StringReader(song.Lyrics));
FdrSong.Document = XamlReader.Load(reader) as FlowDocument;
FdrSong.Document.Background = Brushes.WhiteSmoke;
}
The song was added to the SongSelectionEventArgs when the song was selected from the list. We then go back to the database to grab the lyrics. Originally I had tried to set the background colour of the FlowDocument Reader, Fdr. This didn’t work. The background applies to the document itself, which makes sense when you think about it, I just wasn’t thinking about it clearly enough.
Now to get the words to show on a second monitor. In Winforms there is a class System.Windows.Forms.Screen. One of its properties is AllScreens which is an array of all the screens on the system. There is no corresponding class in WPF, and so no easy way to show the FlowDocumentReader on a second monitor.
So what are the options? One is to host a windows form inside WPF and have that form host the WPF control. I have read that there are problems with that. I think, although I haven’t tried yet, that I would need to set the focus to the second monitor to interact with it. And I don’t want to do that. I want to drive the second monitor from the primary monitor.
The second option is to go back and do everything in Winforms. That is appealing. I am comfortable with Winforms. But there are two problems. The RichTextBox in winforms doesn’t give me the functionality that I can get inWPF. The second problem is that this was an excuse to learn more about WPF.
The third option, and the one that I am going to try now, is to build the application in Winforms but have a number of controls built in WPF. Winforms can host WPF controls, and this will mean that I will have to brush up on interoperability. Any word with that many syllables sounds dangerous, but it seems to be the way to go.
I now need to see how much of what I have already done can be salvaged, and how much must be re-written. But that is often the case in any software project.
One issue I haven’t dealt with is unit testing. And the first rule of development is that if it isn’t tested then it is broken.
So far, I have written very little code. Most of it has been the UI. With the exception of ensuring thatI can put a Section tag into a flowdocument, the commands on the Rich Textbox are all built-in, there is no code. But there will be soon when we change fonts and colours. There is some code to access the database. I don’t like running unit tests against the database too often, but I have written tests for these in a separate project, but it means running against a database in a couple of different states, so once the code is tested we won’t touch these again until we want to do some end to end testing near the completion of the project. Of course, if I add more database access code then I will have to write more tests.
The point is that there is no business logic yet. There may be soon.
Another issue is Linq. LLBL Gen does have Linq to SQL built into the latest version. I haven’t used it, and so far I have found no need. When I get some time I will explore it some more. However, I have used Linq in other projects, and I may use it here. For example, when I get a collection of songs into the list box I might want a search function. I have previously done this with Linq. If the collection, or the TypedList, or Dynamic List, or whatever it is that you use to populate the list box isn’t so big that there is no problem in getting all the data, and it needs to be a lot of data before it becomes an issue, then you may want to filter it down. For example, a list of names may be filtered by the initial of the surname. Linq is easy to use against an existing collection and I may do this.
The reason I haven’t done anything so far is that, at this stage I am uncertain how I want to search. One way is to have a textbox for the search. When a user types in letters the list of songs can be filtered. But there are a couple things that I haven’t decided on. Do I want to start filtering on each keypress? Or do I want the user to enter a string and then, perhaps hit
So now it is off to look at building a winforms application with some WPF components.