<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>midnight muse</title>
	<atom:link href="http://midnightmuse.com.au/feed/" rel="self" type="application/rss+xml" />
	<link>http://midnightmuse.com.au</link>
	<description>Richard Wright's musings about software and other things that take his fancy</description>
	<pubDate>Fri, 19 Sep 2008 03:18:36 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.1</generator>
	<language>en</language>
			<item>
		<title>Another Step Backward</title>
		<link>http://midnightmuse.com.au/2008/08/29/another-step-backward/</link>
		<comments>http://midnightmuse.com.au/2008/08/29/another-step-backward/#comments</comments>
		<pubDate>Fri, 29 Aug 2008 00:37:55 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[Presenter]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/?p=137</guid>
		<description><![CDATA[WPF has a few idiosyncracies that can come back to bite you.]]></description>
			<content:encoded><![CDATA[<p>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&#8217;s constructor I have this line of code:<br />
<code><br />
EventHub.SelectSong += new EventHandler<SongSelectionEventArgs>(EventHub_SelectSong);<br />
</code><br />
EventHub is the class that contains my event declarations. Within Visual studio you just type<br />
<code><br />
EventHub.SelectSong +=<br />
</code> 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.<br />
<code><br />
void EventHub_SelectSong(object sender, SongSelectionEventArgs e)<br />
      {<br />
         song= tasks.GetSongLyrics(e.Song);<br />
         XmlTextReader reader = new XmlTextReader(new StringReader(song.Lyrics));<br />
         FdrSong.Document = XamlReader.Load(reader) as FlowDocument;<br />
         FdrSong.Document.Background = Brushes.WhiteSmoke;<br />
      }<br />
</code><br />
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&#8217;t work. The background applies to the document itself, which makes sense when you think about it, I just wasn&#8217;t thinking about it clearly enough.</p>
<p>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.</p>
<p>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&#8217;t tried yet, that I would need to set the focus to the second monitor to interact with it. And I don&#8217;t want to do that. I want to drive the second monitor from the primary monitor.</p>
<p>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&#8217;t give me the functionality that I can get inWPF. The second problem is that this was an excuse to learn more about WPF.</p>
<p>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.</p>
<p>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.</p>
<p>One issue I haven&#8217;t dealt with is unit testing. And the first rule of development is that if it isn&#8217;t tested then it is broken.</p>
<p>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&#8217;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&#8217;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.</p>
<p>The point is that there is no business logic yet. There may be soon.</p>
<p>Another issue is Linq. LLBL Gen does have Linq to SQL built into the latest version. I haven&#8217;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&#8217;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.</p>
<p>The reason I haven&#8217;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&#8217;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 <Enter> to initiate the search? Even more fundamentally, do I want to search on titles that beging with the search string or titles that contain the search string? These are usability issues that I haven&#8217;t decided yet. I think I am going to have to build the bulk of the app and then see how I want to use it. Or maybe I will come to a decision before that. At the moment it doesn&#8217;t cause me any concern, we will deal with it when we have to.</p>
<p>So now it is off to look at building a winforms application with some WPF components.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2008/08/29/another-step-backward/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Filling the Songs ListBox</title>
		<link>http://midnightmuse.com.au/2008/08/29/filling-the-songs-listbox/</link>
		<comments>http://midnightmuse.com.au/2008/08/29/filling-the-songs-listbox/#comments</comments>
		<pubDate>Thu, 28 Aug 2008 23:45:05 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[Presenter]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/?p=128</guid>
		<description><![CDATA[It is time to show a collection of songs]]></description>
			<content:encoded><![CDATA[<p>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&#8217;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 <a href="http://www.llblgen.com">LLBL Gen Pro</a>.  There are others out there but I have been using this for a few years now and I quite like it.</p>
<p>Some would suggest that using an O/RM is overkill for such a simple database schema. And it is. At this stage I don&#8217;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.</p>
<p>To get a collection of songs is pretty easy.<br />
<code><br />
public EntityCollection<SongEntity> GetAllSongs()<br />
      {<br />
         EntityCollection<SongEntity> songs= new EntityCollection<SongEntity>(new SongEntityFactory());<br />
         ExcludeFieldsList exFields = new ExcludeFieldsList();<br />
         exFields.Add(SongFields.Lyrics);<br />
         ISortExpression sorter = new SortExpression(SongFields.Title | SortOperator.Ascending);<br />
         using(DataAccessAdapter da = new DataAccessAdapter())<br />
         da.FetchEntityCollection(songs,null,0,sorter,null,exFields);<br />
         return songs;<br />
      }<br />
</code><br />
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.</p>
<p>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&#8217;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&#8217;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&#8217;t know yet, so I have set it to varchar(Max). The second line in the method says don&#8217;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.</p>
<p>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<br />
<code><br />
private void FillSongsListBox()<br />
      {<br />
         songs = tasks.GetAllSongs();<br />
         songsListBox.ItemsSource = songs;<br />
      }<br />
</code><br />
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.
</p>
<p>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<br />
<code><br />
public static event EventHandler<SongSelectionEventArgs> SelectSong;</br><br />
public static void OnSelectSong(object sender, SongSelectionEventArgs e)<br />
      {<br />
         if (SelectSong != null)<br />
            SelectSong(sender, e);<br />
      }<br />
</code><br />
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.</p>
<p>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.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2008/08/29/filling-the-songs-listbox/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Editing Songs</title>
		<link>http://midnightmuse.com.au/2008/08/27/editing-songs/</link>
		<comments>http://midnightmuse.com.au/2008/08/27/editing-songs/#comments</comments>
		<pubDate>Wed, 27 Aug 2008 01:36:25 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[Presenter]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/?p=123</guid>
		<description><![CDATA[I just want to edit some text. How can it be so hard?]]></description>
			<content:encoded><![CDATA[<p>After the last post I had some words on the screen. I now need to be able to split them into verses and edit them.</p>
<p>The whole point of a FlowDocument is that it flows. That is, it decides itself when to break into a new page. But I wanted to override this and insert page breaks at the end of each song verse. I spent hours googling and looking at the Microsoft examples One forum response to someone else&#8217;s similar requirement suggested that it couldn&#8217;t be done. I wasn&#8217;t prepared to accept that.</p>
<p>I eventually found that it could be done.</p>
<p>A flowdocument consists of a number of TextElement objects. TextElement is an abstract class and is the base for two abstract classes: Block and Inline. The most common derived class is Paragraph, which is derived from Block. Within a paragraph you can place Inline derived objects such as Span and TextBlock. A typical flowdocument is made up of a number of paragraphs. The flowdocument has a Blocks collection which has a number of methods for navigating through the document.</p>
<p>The Block derived class I needed was Section. A section contains one or more paragraphs. You don&#8217;t need a section but you can insert one if you want. What was important for is that section has a boolean property BreakPageBefore, so now I could insert a page break. So I tried the following code:<br />
<code><br />
Section section = new Section();<br />
          section.BreakPageBefore = true;<br />
          rtb.Document.Blocks.Add(section);<br />
</code><br />
It didn&#8217;t quite work.</p>
<p>This code adds the section, but it adds it to the end of the document, not at the position in the document where the caret is currently positioned. It also doesn&#8217;t move the caret to the new section.</p>
<p>That is OK if I just want to add a new verse at the end, so it is the start of something useful. So I will first deal with getting the insertion point into the new section. In order to add new text I need a paragraph to insert it into. When you press Enter while editing the RTB a new paragraph is inserted automatically. But it isn&#8217;t if you create it programmatically. So the first thing to do is to create a new paragraph and move the insertion point:<br />
<code><br />
rtb.Document.Blocks.Add(new Paragraph());<br />
           EditingCommands.MoveDownByParagraph.Execute(null,rtb);</code><br />
The first line creates a new paragraph. The second line is a built-in command. WPF has a number of these as I mentioned in a previous entry. The first argument, according to the documentation, is ignored by most commands. I haven&#8217;t come across a command yet which uses it, perhaps I will at some stage. It should be set to Null. The second argument is the object which will use the command. The object must implement the IInputElement, and Rich Textboxes do this. The RTB has implementations for a bundle of these commands. So, in effect, I have created a paragraph and moved the insertion point into the new paragraph.</p>
<p>The next problem is to insert a new section with a page break anywhere in an existing flowdocument. This took me a long time to find out how to do. The solution, when I eventually sorted it out, is very simple.</p>
<p>A flowdocument contains a lot of stuff other than plain text. That is the whole point of using a Rich TextBox. In a textbox you can set a selection point with texbox.SelectionStart. There are other methods such as Select, for selecting text using an integer for the start and another integer for the length. There is the SelectedText property and other methods as well. The whole point is that text is stored as a string which is a character array. But in the Rich Textbox there is other stuff in the string, such as pargraph and section tags, formatting tags etc. So using integers to move around text doesn&#8217;t work.</p>
<p>To resolve this issue MicroSoft uses a TextPointer object to represent position within a FlowDocument. The TextPointer will tell us where we are in the document:<br />
<code><br />
//Get the caret position<br />
Textpointer pointer = rtb.Selection.Start;<br />
//Get the paragraph which contains the caret<br />
Paragraph paragraph = pointer.Paragraph;<br />
//Insert the new section after the current paragraph<br />
rtb.Document.Blocks.InsertAfter(paragraph,section);<br />
</code></p>
<p>Almost done. To test all of this I put a button on the form which I clicked to insert a new verse. The button will remain, but we really need a keyboard accelerator. At the moment, to insert a new paragraph you just hit <Enter>. I think that is what a user would expect. I decided that to insert a new page I should follow the convention used in Microsoft Word and use Ctrl + Enter. WPF uses the concept of KeyGesture There are couple of ways to wire this up. I know I am going to need some more key gestures for editing so I first created  private field of type Dictionary to hold all my key getstures.<br />
<code><br />
private Dictionary<KeyGesture,RoutedEventHandler> gestures =<br />
   new Dictionary<KeyGesture,RoutedEventHandler>();<br />
</code><br />
When the Edit Control loads it calls a method to add gestures, in this case there is only one at the moment.<br />
<code><br />
gestures.Add(new KeyGesture(Key.Enter,ModifierKeys.Control),AddNewVerse);<br />
</code><br />
This line of code says that the Gesture compring the Control Key + the Enter Key will call the AddNewVerse method, which is the method which contained the earlier code for inserting paragraphs and sections.</p>
<p>I now need to hook this up to the KeyDown event of the Rich TextBox.<br />
<code><br />
private void rtb_PreviewKeyDown(object sender, KeyEventArgs args)<br />
      {<br />
         foreach (KeyGesture gesture in gestures.Keys)<br />
         {<br />
            if (args.Handled) return;<br />
            if (gesture.Matches(null, args))<br />
            {<br />
               gestures[gesture](this, args);<br />
               args.Handled = true;<br />
            }<br />
         }<br />
      }</code><br />
In this code args is of type KeyEventArgs. The code looks through the dictionary of key gestures seeking a match. If it finds a match it executes the method in the dictionary. It then sets the handled property to true so that it won&#8217;t do anything else. Otherwise it would raise the event for the Enter key and insert another paragraph. I could let it do that and not insert the paragraph myself in the AddNewVerse method. But if I add more gestures I could run into problems. I think it is safer to tell it explicitly what you want done.</p>
<p>And that is it for this time.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2008/08/27/editing-songs/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Rich Text Box</title>
		<link>http://midnightmuse.com.au/2008/08/22/the-rich-text-box/</link>
		<comments>http://midnightmuse.com.au/2008/08/22/the-rich-text-box/#comments</comments>
		<pubDate>Fri, 22 Aug 2008 08:10:14 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[Presenter]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/?p=114</guid>
		<description><![CDATA[The Rich Text Box in WPF is a different animal than the one in winforms]]></description>
			<content:encoded><![CDATA[<p>I want to edit my songs, and in the editing I want to put some formatting. The Rich Text Box is the control to do this. Even in Winforms, the Rich Text Box would be the way to go. But in WPF it behaves differently.</p>
<p>The first thing that you notice is that the Rich Text Box (RTB from now on) does not have a text property. It contains a Flowdocument. A flowdocument is a new concept in WPF. It represents a document which can flow, naturally enough. It will take up all the available space on a page and flow onto extra pages. This, of course, all depends upon the size of the pages. A flow document is read with either a FlowDocumentReader, a FlowDocumentPageViewer or a FlowDocumentScrollViewer. The FlowDocumentPageViewer shows the document page by page. The FlowDocumentScrollViewer shows the entire document in continuous scrolling mode. The FlowDocumentReader allows you to choose either of these two modes or two pages at a time. With each of these you can adjust the zoom on the page. So they are fairly flexible.</p>
<p>A FlowDocument is just a piece of xaml code. The text is contained within paragraph tags in the xaml.</p>
<p>The nice thing about the RTB is that it has all the editing functions built in. Many of these are already hooked up to keyboard shortcuts. Placing the cursor over a word and hitting Ctrl+B will make the entire word Bold. EditingCommands has more methods than you would ever want to use. There is really very little need to add much, or anything, in order to have a fully functioning editor. WPF uses commands to attach behaviour to controls. There is also the standard events, and another new concept, triggers. We will look at these in a later post when we get to wire everything up.</p>
<p>One thing which did arise as a result of playing with this stuff was the question of how I would arrange and store the data. I had earlier said that I would prefer to store the data in a database. My original thinking was that I would store an entity called song, and a related entity verse. A song could have one or many verses. In that scenario it made sense to use a database.</p>
<p>Upon reflection I am close to abandoning that idea. I am thinking that each song would contain all its lyrics in one xaml file. If that is the case then the database would only have one table and I am starting to think that there is no need for it.</p>
<p>I may still change my mind about the song and verses, we will see how it pans out. But for, since I have the database set up I am using it, but will probably abandon it later. To read the flowdocument from the database I need a memory stream. If I go with a file system instead of a database I will just use a file stream. So there is no big change.</p>
<p>One area where I did run into trouble was getting the flowdocument from the RTB. This bit is easy:<br />
<code>FlowDocument doc = rtb.Document;</code><br />
No problem, I now have the flowdocument contained within the RTB. But what can I do with it. I can&#8217;t cast it to a string to save it, and if I want to save it to a file then I am out of luck. After a bit of searching on the web I found that I could do this:<br />
<code><br />
          TextRange range = new TextRange(rtb.Document.ContentStart,rtb.Document.ContentEnd);<br />
          MemoryStream stream = new MemoryStream();<br />
           range.Save(stream,DataFormats.Xaml);</code><br />
In this case the range is from the beginning of the document to the end. range.Save saves the range into the new stream using the DataFormats provided. There are a number of DataFormats, including Xaml, XamlPackage and Rtf. However, doing this introduces a lot of unnecessary cruft into the string. I then found a much simpler way to save:<br />
<code> string lyrics = XamlWriter.Save(rtb.Document);</code><br />
And this only saves the flowdocument itself into the string. There are overloads so you can save to a stream, for example a file stream. I found doing this that I was able to do away with my memorystream altogether.</p>
<p>Reading the flowdocument from the database was nearly as easy:<br />
<code><br />
           XmlTextReader reader = new XmlTextReader(new StringReader(song.Lyrics));<br />
           FlowDocument doc = (FlowDocument) XamlReader.Load(xmlTextReader);<br />
           rtb.Document = (FlowDocument)XamlReader.Load(reader);</code><br />
So using the database is easy. Whether I will keep it is another question.</p>
<p>The next step is parsing the flowdocument to split it up into verses. That is a job for tomorrow.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2008/08/22/the-rich-text-box/feed/</wfw:commentRss>
		</item>
		<item>
		<title>More on the UI</title>
		<link>http://midnightmuse.com.au/2008/08/20/more-on-the-ui/</link>
		<comments>http://midnightmuse.com.au/2008/08/20/more-on-the-ui/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 22:39:35 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[Presenter]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/?p=112</guid>
		<description><![CDATA[Presentation Foundation and Winforms can be used together]]></description>
			<content:encoded><![CDATA[<p>One thing I hadn&#8217;t thought of yesterday when I wrote about the UI is the possibility of using WPF and winforms together.</p>
<p>I have read, although I haven&#8217;t tried it yet, that winforms can host WPF, and vice versa. At some stage through this project I will run an experiment on that. It isn&#8217;t urgent yet, but it is something that is worth keeping in mind.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2008/08/20/more-on-the-ui/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A Start with the UI</title>
		<link>http://midnightmuse.com.au/2008/08/19/a-start-with-the-ui/</link>
		<comments>http://midnightmuse.com.au/2008/08/19/a-start-with-the-ui/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 05:38:13 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[Presenter]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/?p=89</guid>
		<description><![CDATA[Time to make an initial start with the User Interface]]></description>
			<content:encoded><![CDATA[<p>I often look back at the old days of programming. A computer couldn&#8217;t do much so not much was expected. But things have changed. I now spend more and more time trying to build a decent looking user interface. I read a few weeks ago, and I wish I could find the quote, something along the lines of <em>A designer shoots bullets, a developer throws them.</em> I am not a designer, so I am throwing bullets at the screen rather than shooting them, and I am sure that they are having the same effect as throwing them – not much.</p>
<p>Nevertheless, you need a UI of some sorts, so I built one. Here is a screen shot of where it is at now.<a rel="attachment wp-att-90" href="http://midnightmuse.com.au/2008/08/19/a-start-with-the-ui/ribbon/"><img class="aligncenter size-medium wp-image-90" title="Ribbon" src="http://midnightmuse.com.au/wp-content/uploads/2008/08/ribbon-300x60.jpg" alt="First attempt at ribbon menu" width="600" height="60" /></a></p>
<p>There are a few things to say about this ribbon bar. Microsoft has produced a Ribbon Bar but the licensing is far too restrictive to be of much use. In any case, they don&#8217;t have one for WPF. So you have to build your own. This obviously needs more styling before it is completed, but we will look at some of the details of the ribbon as it stands at the moment.</p>
<p>First, it is a separate control. You could build it all on the main form,  but I think it is better to separate your controls into separate classes – it is standard OO good practice. At the moment I am trying out Expression Blend 2.5 June 2008 Preview. I have had a few issues with it, it sometimes hangs or crashes Visual Studio. But I am running the Beta of Visual Studio 2008 SP1, and I think the release version of SP1 might fix this. This was released in the last few days.</p>
<p>Expression Blend is primarily a designer&#8217;s tool. And I find it easier to do some of the work in Blend and some in Visual Studio. Having two large monitors really helps if you are using these two together.</p>
<p>When  you create a new user control Blend defaults to using a grid as the layout container. In this case I could have used a different container, but it doesn&#8217;t really matter, at least I don&#8217;t think it does. I left it as a grid. Within the grid I have a Tab Control, and I will add some styling to the tab headers when I get to the stage of trying to make it pretty. At the moment the only tab with any content is the <strong>Songs</strong> tab because this is where all the editing will go.</p>
<p>Within this tab control I have a Stackpanel aligned horizontally, These contain File, Edit, Font and Arrange sections. Each of thse sections contains a grid. The first two, File and Edit, have four columns and three rows. The bottom row contains a border which contains a TextBlock which spans all the columns and is horizontally aligned to the centre. The border is set with a colour, a thickness and a radius for the rounded corners.</p>
<p>In the top row, in each column, is a button. The button contains an image. And below the button is a Textblock with the text of the control, eg New, Open etc. The button and the textblock are also contained within a border which spans all four columns and two rows, and has a border colour and thickness, and rounded corners.</p>
<p>The nice thing about WPF is that any control, well most controls, can contain almost any content you want. In winforms a button had a text property. If you wanted a button with an image you needed to create your own button by subclassing the button class, or building some button like properties and events into an image. WPF is different. Controls have a property called Content and you can put almost anything into it. For example, you could have the content of a button be another button. I don&#8217;t know why you would do that, but you could. You are also able to edit the individual components of the button to style it in all manner of ways. There is a lot information about WPF styling on the web.</p>
<p>The font section contains some interesting features. The first combo box is a list of fontstyles. This is the xaml to set the fontstyle combo.<br />
<code><br />
&lt;ComboBox IsSynchronizedWithCurrentItem="True"<br />
                                  ItemsSource="{x:Static Fonts.SystemFontFamilies}"<br />
                                  x:Name="cmbFont" HorizontalAlignment="Stretch"<br />
                                  VerticalAlignment="Center" Margin="10,0,5,0"<br />
                                  BorderBrush="{x:Null}" Style="{DynamicResource ComboBoxStyle1}"<br />
                                  Width="Auto" FontSize="14"&gt;<br />
                            &lt;ComboBox.ItemsPanel&gt;<br />
                                &lt;ItemsPanelTemplate&gt;<br />
                                    &lt;VirtualizingStackPanel /&gt;<br />
                                &lt;/ItemsPanelTemplate&gt;<br />
                            &lt;/ComboBox.ItemsPanel&gt;<br />
                            &lt;ComboBox.ItemTemplate&gt;<br />
                                &lt;DataTemplate&gt;<br />
                                    &lt;TextBlock Text="{Binding}" FontFamily="{Binding}"<br />
                                               FontSize="14"<br />
											   Height="20" /&gt;<br />
                                &lt;/DataTemplate&gt;<br />
                            &lt;/ComboBox.ItemTemplate&gt;<br />
                        &lt;/ComboBox&gt;</code></p>
<p>There are a few things to notice here. The Items source binds the combo box to the System Fonts. Then the Itemspanel declares a template, ItemsPanelTemplate which contains a Virtualizing StackPanel. This means that items are arranged in a stack. You can leave this out and it will include it by default, but not until after it has retrieved all the data. By specifically declaring the Virtualizing Stack Panel the list loads faster. Although I seem to remember a warning about this. I need to look further into it. The interesting thing is the TextBlock. The ItemTemplate says that the items in the combo box will be rendered using a Textblock. The text of the text block is bound to its parents datasource, hence Text=&#8221;{Binding}&#8221; And the font used in the Textblock is bound to the font family of the datasource. So each item in the combo box is rendered in the specific font.</p>
<p>Combo boxes and List boxes are much more versatile in WPF than winforms.</p>
<p>A similar thing happens with the font colours. There is a button whose event handler is wired to a popup control. When the button is clicked the popup appears. The popup contains a listbox. A separate class contains a dictionary of colours. Specifically I have declared a Dictionary&#038;ltstring, Brush&gt;/. Brush is used in WPF to declare the colours which will be used to render items, paint backgrounds, borders etc. So the string is the colour name, and the brush is, for example Brushes.Black.  When the listbox is populated a new ListBoxItem is created for each item in the dictionary. The Item is the string and the colour of the item is the Brush colour.</p>
<p>The next thing to do is to wire up some events. More on that next time.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2008/08/19/a-start-with-the-ui/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Presentation Part 2</title>
		<link>http://midnightmuse.com.au/2008/08/18/presentation-part-2/</link>
		<comments>http://midnightmuse.com.au/2008/08/18/presentation-part-2/#comments</comments>
		<pubDate>Mon, 18 Aug 2008 04:27:12 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[Presenter]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/?p=88</guid>
		<description><![CDATA[Presentation Software &#8211;design considerations]]></description>
			<content:encoded><![CDATA[<p>It is time to get down to the details of what the Presentation Application &#8211; let&#8217;s call it <em>Presenter</em> for now &#8211; will do. This is a first look at the required functionality</p>
<ul>
<li>Show list of all songs and other types of items. I will call everything a song for the moment.</li>
<li>Allow editing of songs, adding, deleting and modifying.</li>
<li>Show the songs on a separate screen, usually through a projector.</li>
</ul>
<p>That&#8217;s a reasonable start. But even this short list has a number of ramifications. </p>
<ul>
<li>Obviously we need a UI of some sort, with a menu, and, I think, associated keyboard commands.</li>
<li>Where do we store the data, and in what format?</li>
<li>How will I program the application?</li>
<li> There is also the more fundamental question. We need to determine where the application will run.</li>
</ul>
<p>I will deal with the last point first.
</p>
<p>I am writing this primarily for myself. I program in Windows, and I use Windows. So it is going to run on Windows. However, if it works OK it would be nice if others could use it. That being said it makes sense to ensure that the app will run on XP and Vista. Anything earlier than XP is not worth worrying about. I know some people are still using Windows 98, but there are not too many of them left. I have had no experience with Windows 2000, and I am not sure of the differences and I am not going to bother finding out.</p>
<p>My current programming environment of choice is .NET. I use 3.0 or 3.5, but I can target the 2.0 framework, although that is not a primary concern. If anyone wants to use this there is a fair chance that they will have to download the framework, or get it somewhere so it doesn&#8217;t matter much which one they get. My preferred language is C# so we are set. Almost.</p>
<p>The most important decision concerning the environment is this $#8211; do I write a standards winforms application or a Windows Presentation Foundation (WPF) application? There are arguments on both sides. I have been writing winforms for years and am pretty comfortable with it. WPF, on the other hand has a lot going for it. It is likely to be the standard for Windows client applications in the future. There is a lot you can do with it. And, while I have been playing around with it, it is still fairly new to me. Part of the problem is that much of the design is done in xaml (Extensible Application Markup Language) which is xml with the appropriate namespaces, more or less. But it does follow the rules of xml. I am more comfortable with c# code than xaml. You can, of course, write all the WPF stuff in c#, but some of it would be a nightmare to do. It is a lot easier in xaml. So which to choose?</p>
<p>The answer really comes down to what I want the application to look like. There will be a few screens for editing songs and sorting out which song to display, but essentially the application is a presenter on a separate screen. How am I going to show the songs on a screen? There are probably two ways to do this &#8211; there may be more but I can&#8217;t think of them off the top of my head. I could use HTML and show the songs in a browser. Or I could put the songs in a Rich Textbox. HTML has its appeal, but this is still a client application. I don&#8217;t, at this stage, want to go down the web route. A Rich Textbox will show all the formatting and it will also allow the editing to be done in a similar control. I am leaning towards the Rich Textbox.</p>
<p>Winforms and WPF both have Rich Textbox controls. But they work differently. In Winforms the content is held in RTF (Rich Text Format). To save it to a database I think I would need to store the data in a binary field and I think it would be pretty big. There is a lot of formatting to be saved along with the text. I could also save it as an rtf file, but these are also pretty big. But this is an option.</p>
<p>WPF, on the other hand, stores its Rich Textbox content in a new format call a Flowdocument. This has a number of advantages. First, it means that we don&#8217;t, in fact, need a Rich Textbox to display the data. The song can be edited in a textbox but then displayed using a Flowdocument reader. Alternatively, the document can be transformed into a Fixeddocument and displayed using a document reader. I&#8217;m not sure if this is a help or not, but it may be. Secondly, the flowdocument is just xaml, and so it can be stored as a xaml file or stored in a database. I&#8217;ll get to the database shortly. </p>
<p>So, with either winforms or WPF I can store the songs as either files, or as fields within a database. With WPF, however, regardless of how they are stored, the songs will be smaller, and I think that will be a benefit for load times. So which one. WPF gives me more options at how I display. It gives me more eye candy on the UI. And it is an environment that I really need to come to grips with. So WPF it is. I may regret this decision and change my mind later. Against this, I do have some nice UI stuff for Winforms. I use the <a href="http://www.devexpress.com/">DevelopExpress</a> suite of tools for UI in winforms and they are pretty good. If I decide that WPF was a mistake I can go back and build the UI in winforms. The logic will be the same regardless.</p>
<p>The final question is where to store the songs.  I much prefer the idea of storing them in a database than in files. If it was a matter of just storing text then I don&#8217;t think there is any question. But this is formatted text. So text files may be a better option. If we go the database route there is then the question of what type of data field do we store them in. SQLServer, and some other databases, I believe, have an xml datatype. Xaml is xml, so I could use the xml data type. But the xaml is also just a string. In order to get it into and out of a Rich Textbox or a FlowDocument, I think I would need a stream. That may give rise to the question of encoding. .NET uses UTF16 for characters. Does that mean that if I would need to store as nvarchar rather than varchar? At this stage I have no idea &#8211; this is all new to me, I have rarely worked with streams, except for opening and closing files, and updating them etc. But it isn&#8217;t a big problem, it is just a matter of performing a few experiments.</p>
<p>But, in any case, it doesn&#8217;t matter now. I know that I can store the data in either a database, in some form, or else in files. So I will proceed on the basis that I will be reading and writing flowdocuments, where I will read them from or write them to is an implementation issue that can be put off until we need to address it.</p>
<p>The next step will be some early design work on a basic UI. It will not have to do everything yet, but I want to get a feel for what the application will look like so that I can assure myself that it will work, from a users point of view. That will be the subject of the next post.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2008/08/18/presentation-part-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Presentation Software</title>
		<link>http://midnightmuse.com.au/2008/08/16/presentation-software/</link>
		<comments>http://midnightmuse.com.au/2008/08/16/presentation-software/#comments</comments>
		<pubDate>Sat, 16 Aug 2008 04:26:05 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[Presenter]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/?p=87</guid>
		<description><![CDATA[PowerPoint has its shortcomings, but so do most of the other options]]></description>
			<content:encoded><![CDATA[<p>First some background. I attend a church which, like many others, uses a projector to show the hymns or songs which are to be sung. We also project other parts of the service, some prayers and some items which require a response from the congregation.</p>
<p>
Many churches, including ours, have followed a similar route. We start out with books. In our case, being an Anglican Church, that consists of a hymn book and a prayer book. There are also pew Bibles so that the congregation can follow along when the Bible passage is read. This, in itself, is a problem. You have three books to juggle, and for some people, especially newcomers, it is difficult to know which book you are supposed to be reading and where in that book you are up to. We still do this at our fairly traditional 8:30 am service.</p>
<p>
One church I used to attend in Southern NSW printed the whole service each week. This solved the problem of books, but it meant a lot of printing and a lot of wasted paper. They realised that this was not a long term solution and were looking for an alternative.</p>
<p>
After using books, the next step in the progression, for many places was an overhead projector. There was still a lot of time spent in preparing the slides, but they could be re-used. In many churches just the songs were on overhead.</p>
<p>
But now we are in the technological age and we have <a href="http://office.microsoft.com/en-gb/powerpoint/default.aspx">PowerPoint.</a></p>
<p>
I must admit, at the outset, that I hate PowerPoint with a vengeance. That&#8217;s not exactly true &#8211; it isn&#8217;t PowerPoint, per se, that I hate, it is the way it is used. Too often PowerPoint has been used as a substitute for good preparation. PowerPoint itself is pretty good, it is just used badly. I also wonder if it is always used legally, but that is another issue.</p>
<p>What is the problem with PowerPoint for church service presentation? First, it is slow to change slides, although I can live the speed. But there is a noticeable lag when changing from one slide to the next. Second, you are locked into the presentation that you have prepared. So often at church someone comes to me just before the service starts and says that we need to make a change. Perhaps a musician has a problem with one of the songs. Or you need to insert a couple of new slides. This can all be done, but it takes time. The final problem, which isn&#8217;t the fault of PowerPoint, is that there are so many different animation effects that can be used to move from one slide to the next. You can have fade and slide and checkerboard and up and down and left and right blinds, and all of these come in a variety of styles. Functionality is good. Flexibiity is good. But just because you can do something doesn&#8217;t mean that you should. And some PowerPoint presentations look horrible. PowerPoint used well by someone with some graphic design skills is great, usually it is just rubbish.</p>
<p>So what are the alternatives? There are a number. We have been trying out <a href="http://www.zionworx.org.uk/">Zionworx</a> and it isn&#8217;t too bad. It is also free. There are a number of commercial packages around, one of the better know ones being <a href="http://www.mediashout.com/">MediaShout</a>. I had a look at the express version, there is also a starndard version. Express version costs $229 and the standard version costs $429. I think these are $US prices. The Standard version may do what I want, but the express version does not. Neither does Zionworx, nor a number of other packages that I tried. Most of the others cost serious dollars, Zionworx seems to be the only free version I could find.</p>
<p>I don&#8217;t mind paying for software. I spend a lot of money on software. But there were two problems with buying a commercial package. The first is that I don&#8217;t want it, the church does, and I think that I would have had a hard time getting them to spend around AUD$500 on presentation software. Second, I wouldn&#8217;t spend that kind of money on something that doesn&#8217;t do what I want.</p>
<p>What is the problem with these packages? Unlike PowerPoint they don&#8217;t give enough formatting options. For example, when we display a song we just want the words to appear in a large readable font. All the packages do this. They provide a number of formatting options, fontface, size, background colour or a background graphic, foreground colour. But the formatting applies to the whole item being displayed. We often have some responsive items. The service leader will say something and the congregation will respond. In PowerPoint we used a white foreground for the service leader&#8217;s words, and a yellow foreground for the congregation&#8217;s response. In Zionworx I cannot do this.</p>
<p>The reason I can&#8217;t do it is because the displayed items are held in a database in text format. The styling is applied to the whole slide, or item being presented. Keeping the data in a database is, in my mind, the right way to go. The data is pulled from the database in one go and is immediately available. The rendering on the screen is very fast. There is no discernible delay in moving from one screen to the next. But it cannot be formatted at a level of granularity that suits us.</p>
<p>What to do? The only thing that a programmer would do in this situation is write my own. How did this pan out? See the next post.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2008/08/16/presentation-software/feed/</wfw:commentRss>
		</item>
		<item>
		<title>VisualSVN</title>
		<link>http://midnightmuse.com.au/2007/12/05/visualsvn/</link>
		<comments>http://midnightmuse.com.au/2007/12/05/visualsvn/#comments</comments>
		<pubDate>Wed, 05 Dec 2007 01:49:35 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/2007/12/05/visualsvn/</guid>
		<description><![CDATA[Integrating Subversion into Visual Studio has never been easier]]></description>
			<content:encoded><![CDATA[<p>Everyone needs source control of some sort. You might think it is unnecessary for a small one-man or one-woman operation like mine. I used to think that. But I have been using Subversion for some years now, and I find it indispensible. <a href="http://software.ericsink.com/">Eric Sink</a> has an old but still very relevant  <a href="http://software.ericsink.com/item_10134.html"> article explaining single user source control</a>.</p>
<p>If you are new to source control then Eric has also written a <a href="http://software.ericsink.com/scm/source_control.html">Source Control Howto</a>. This is aimed at SourceGear&#8217;s own product, Vault, but most of what he says is generally applicable to any source control product.</p>
<p>If, like me, you use Subversion then there is also <a href="http://svnbook.red-bean.com/nightly/en/">online documentation</a> available.</p>
<p>I should say, at the outset, that I don&#8217;t consider Subversion to be better than Vault. I use it because it is what I got to know and it works for me. One of the things about being a solo developer is that any of the minor differences between the various source control systems are largely irrelevant. I don&#8217;thave to worry about locking files, or how different files are merged. Working on my own means that concurrency issued just do not arise.</p>
<p>In the past I have used Subversion as a Windows service. There are two ways you can set it up, either as a service or as an Apache server. The service was easier to set up and I haven&#8217;t had the need to provide access via http. I also installed TortoiseSVN which is a Subversion client which integrates with Windows Explorer. Everything has worked well.</p>
<p>Some people have integrated source control with Visual Studio. I have never felt the need to do this. There were two reasons. First, I version more than source files. For example, I version documentation, not because of the versioning, but because it provides an easy backup. And secondly, because I stick more than source files into the source control, it seemed to me to be a separate exercise to the coding.</p>
<p>But there are some problems with this approach. The main one is forgetting to commit my changes. It goes something like this.  I work at home in an office outside of, but attached to, our house. This is a good way to work. It means that I leave the house to go to work. But early in the evening my wife is likely to come out and tell me that dinner is ready. So I stop what I am doing and go and eat. Then I have coffee after dinner, maybe watch some TV, and figure that I am not going back to work. So I go back to the office to turn everything off. By now it is raining, and cold, and I want to get back inside in the warmth. I&#8217;ll check in my work in the morning, I say. But, of course, I don&#8217;t. I figure I&#8217;ll just make a few more changes and then check it in.</p>
<p>So I decided that I needed something better. I could, of course, embark on a course of self-discipline, but from past experience I know that that won&#8217;t work.</p>
<p>I then discovered <a href="http://www.visualsvn.com/">VisualSVN</a>. This integrates TortoiseSVN into Visual Studio, and it works with VS 2003, 2005, and the lastest version with VS2008. And I have to say it is brilliant. Because it uses TortoiseSVN I still have access to the tight integration with Windows Explorer for those files that do not form part of the development. And it is not intrusive. There are small, but noticeable, icons, like traffic lights, next to the files in Solution Explorer. After using it for a morning I am hooked.</p>
<p>VisualSVN is not free. There is a 30 demo, completely uncrippled. After that it is US$49. Given the good exchange rate between the AUD and USD at the moment it seems like a worthwhile investment.</p>
<p>VisualSVN works with Subversion as a service. However, they also have a free product called VisualSVNServer which is an Apache based server. I thought I would give this a go just to see what I thought. I didn&#8217;t want to spend time setting up a server but I thought, what the heck. VisualSVNServer is a 6meg download. You get an msi file and it just installs. You tell it where to install and where to put your repository. You can change port settings if you want. I didn&#8217;t need to. The thing that I thought might cause me a problem is that I am running 64 bit Vista. But it didn&#8217;t seem to care. It just installed and it runs fine.</p>
<p>If you want Source control, and if you are a developer then you need it, and you want integration with Visual Studio, and you want a simple install then this is the product for you. You will also need to install TortoiseSVN, but it is also a very simple installation process.</p>
<p>So far I couldn&#8217;t be happier.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2007/12/05/visualsvn/feed/</wfw:commentRss>
		</item>
		<item>
		<title>I&#8217;ve lost my Zoo</title>
		<link>http://midnightmuse.com.au/2007/11/26/ive-lost-my-zoo/</link>
		<comments>http://midnightmuse.com.au/2007/11/26/ive-lost-my-zoo/#comments</comments>
		<pubDate>Sun, 25 Nov 2007 23:40:04 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/2007/11/26/ive-lost-my-zoo/</guid>
		<description><![CDATA[Facebook animals are notoriously fickle]]></description>
			<content:encoded><![CDATA[<p>A friend suggested that I have a look at <a href="http://www.facebook.com/">Facebook</a>. I am sure that you have heard of it. Most likely you are already signed up.</p>
<p>So I had a look. Unfortunately, you cannot look at much without joining. So I joined.</p>
<p>Now I have some Facebook friends. I think I have more virtual friends than real ones. My daughter, a Facebook afficianado, told me to get an aquarium and a zoo. So I did, and promptly ignored them. Facebook animals do not like being ignored.</p>
<p>My zoo is now a barren wasteland, not a plant or animal to be seen. I am sure my aquarium will soon go the same way. Although, at the moment, my daughter is feeding my fish.</p>
<p>My great fear is that by ignoring my Facebook friends they, too, will also desert me. I will be left a lonely, virtual pariah.</p>
<p>So there you go. Facebook is an exact replica of real life!</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2007/11/26/ive-lost-my-zoo/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
