<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Niners/c4f.Rudi-Grobler/Posts/RSS"></atom:link>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9</title>
      <link>http://channel9.msdn.com/Niners/c4f.Rudi-Grobler/Posts</link>
    </image>
    <itunes:image href=""></itunes:image>
    <itunes:category text="Technology"></itunes:category>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Niners/c4f.Rudi-Grobler/Posts</link>
    <language>en</language>
    <pubDate>Tue, 21 May 2013 00:59:18 GMT</pubDate>
    <lastBuildDate>Tue, 21 May 2013 00:59:18 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>1</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Classic JukeBox</title>
      <description><![CDATA[
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/CJBLogo_2.jpg"><img title="CJBLogo" border="0" alt="CJBLogo" align="right" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/CJBLogo_thumb.jpg" width="240" height="79"></a>
 Remember the <a href="http://www.brookstone.com/shop/product.asp?product_code=548677&amp;cm_ven=Compare&amp;cm_cat=ChannelAdvisor&amp;cm_pla=msn&amp;cm_ite=datafeed">
classic arcade style jukeboxes</a>? Today we will be creating our own jukebox using WPF, WMP, a little bit of 3D, some very basic electronics (costing less than $10 USD) and a splash of M-V-VM</p>

<h2>Introduction</h2>
<p>A couple of weeks ago I took my son to the game arcade to play a little… while playing, I noticed in the corner a old jukebox… I started wondering how difficult it would be to recreate one of these using “real” hardware and WPF? This article explorers how
 to make real hardware control software applications in a practical manner</p>
<h4>M-V-VM</h4>
<blockquote>
<p><em>“Once a developer becomes comfortable with WPF and MVVM, it can be difficult to differentiate the two. MVVM is the lingua franca of WPF developers because it is well suited to the WPF platform, and WPF was designed to make it easy to build applications
 using the MVVM pattern (amongst others). In fact, Microsoft was using MVVM internally to develop WPF applications, such as Microsoft Expression Blend, while the core WPF platform was under construction. Many aspects of WPF, such as the look-less control model
 and data templates, utilize the strong separation of display from state and behavior promoted by MVVM.”</em></p>
</blockquote>
<p><a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx">WPF Apps With The Model-View-ViewModel Design Pattern by Josh Smith</a></p>
<p>The M-V-VM pattern helps to separate the logic from the UI which is VERY important when you actually want to manipulate the logic from external sources (Like real push buttons). Our MediaViewModel is extremely simple…</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/ViewModel_2.jpg"><img title="ViewModel" border="0" alt="ViewModel" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/ViewModel_thumb.jpg" width="168" height="246"></a>
</p>
<p>The MediaViewModel has a collection of albums (Which gets fetched when Initialize() is called) and also exposes some commands</p>
<h2>Setting up Windows Media Player media library</h2>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/WMPMediaLibrary_2.jpg"><img title="WMPMediaLibrary" border="0" alt="WMPMediaLibrary" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/WMPMediaLibrary_thumb.jpg" width="500" height="273"></a>
</p>
<p>Ensure that your Windows Media Player (WMP) media library has some media. I added a few albums to my library by clicking on the Add to library… menu option.</p>
<p><strong>TIP</strong> - I also ensured that all my CD's that I do add has full ID3 tags and album art</p>
<h4>Fetching WMP media library</h4>
<p>To fetch the media library from WMP, we have to use a little bit of COM</p>
<blockquote>
<p><em>“Microsoft COM (Component Object Model) technology in the Microsoft Windows-family of Operating Systems enables software components to communicate. COM is used by developers to create re-usable software components, link components together to build applications,
 and take advantage of Windows services. The family of COM technologies includes COM&#43;, Distributed COM (DCOM) and ActiveX® Controls.”</em></p>
</blockquote>
<p>Adding a reference to a COM component is just as easy as adding a reference to a .NET assembly. Click the Project menu and select Add Reference, then click the COM tab on the Add Reference dialog.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/AddWmpComReference_2.png"><img title="AddWmpComReference" border="0" alt="AddWmpComReference" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/AddWmpComReference_thumb.png" width="469" height="461"></a>
</p>
<p>The WMP library is a flat structure of media items, so the Albums -&gt; Tracks hierarchy must be created manually. Here is our Model</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/Model_2.jpg"><img title="Model" border="0" alt="Model" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/Model_thumb.jpg" width="372" height="200"></a>
</p>
<p>We will be abstracting the fetching of the data by using a IMediaLibraryRepository. By using a interface we have the added advantage of supporting other media sources (like iTunes, etc) in the future</p>
<p><strong>C#:</strong></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">interface</span> IMediaLibraryRepository 
{ 
    IList&lt;Album&gt; GetAlbums(); 
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>And here is our WMP-specific implementation</p>
<p><strong>C#:</strong></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> WMPMediaLibraryRepository : IMediaLibraryRepository 
{ 
    <span class="kwrd">public</span> IList&lt;Album&gt; GetAlbums() 
    { 
        List&lt;Album&gt; Albums = <span class="kwrd">new</span> List(); 
        WindowsMediaPlayer wmp = <span class="kwrd">new</span> WindowsMediaPlayer(); 
        IWMPPlaylist playlist = wmp.mediaCollection.getAll(); 
        <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; playlist.count; i&#43;&#43;) 
        { 
            IWMPMedia media = (IWMPMedia)playlist.get_Item(i); 
            
            Track track = <span class="kwrd">new</span> Track(); 
            track.Title = media.getItemInfo(<span class="str">&quot;Title&quot;</span>); 
            track.Location = media.getItemInfo(<span class="str">&quot;SourceUrl&quot;</span>); 
            track.Number = media.getItemInfo(<span class="str">&quot;OriginalIndex&quot;</span>); 
            <span class="kwrd">string</span> albumName = media.getItemInfo(<span class="str">&quot;Album&quot;</span>); 
            
            var album = (from a <span class="kwrd">in</span> Albums 
                            <span class="kwrd">where</span> a.Name == albumName 
                            select a).FirstOrDefault(); 
            
            <span class="kwrd">if</span> (album != <span class="kwrd">null</span>) 
            { 
                album.Tracks.Add(track); 
            } 
            <span class="kwrd">else</span> 
            { 
                Album a = <span class="kwrd">new</span> Album(); 
                a.Name = albumName; 
                <span class="kwrd">string</span> dir = System.IO.Path.GetDirectoryName(track.Location); 
                FileInfo file = <span class="kwrd">new</span> FileInfo(System.IO.Path.Combine(dir, <span class="str">&quot;Folder.jpg&quot;</span>));                 
                <span class="kwrd">if</span> (file.Exists) 
                { 
                    a.Cover = file.FullName; 
                } 
                a.Artist = media.getItemInfo(<span class="str">&quot;AlbumArtist&quot;</span>); 
                a.Tracks.Add(track); 
                <span class="kwrd">if</span> (albumName != <span class="kwrd">string</span>.Empty) 
                { 
                    Albums.Add(a); 
                } 
            } 
        } 
        <span class="kwrd">return</span> Albums; 
    } 
}</pre>
<h2>Commands</h2>
<p>All the interaction between the View and the ViewModel happens by using ICommand. We will be using the RelayCommand</p>
<blockquote>
<p><strong>RelayCommand</strong> - An ICommand whose delegates can be attached for Execute and CanExecute</p>
</blockquote>
<p>The MediaViewModel exposes the following commands</p>
<ul>
<li>NextAlbum </li><li>PreviousAlbum </li><li>SongUp </li><li>SongDown </li><li>PlaySong </li></ul>
<p>To create a RelayCommand, we first need the CanExecute and Execute delegates</p>
<p><strong>C#:</strong></p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">bool</span> SongUpCanExecute(<span class="kwrd">object</span> parameter) 
{ 
    <span class="kwrd">return</span> (TracksCollectionView.CurrentPosition &gt; 0); 
} 

<span class="kwrd">private</span> <span class="kwrd">void</span> SongUpExecute(<span class="kwrd">object</span> parameter) 
{ 
    <span class="kwrd">if</span> (TracksCollectionView != <span class="kwrd">null</span>) 
    { 
        TracksCollectionView.MoveCurrentToPrevious(); 
    } 
}</pre>
<p>And then create the command</p>
<p><strong>C#:</strong></p>
<pre class="csharpcode"><span class="kwrd">private</span> ICommand songUp; 
<span class="kwrd">public</span> ICommand SongUp 
{ 
    get 
    { 
        <span class="kwrd">if</span> (songUp == <span class="kwrd">null</span>) 
        { 
            songUp = <span class="kwrd">new</span> RelayCommand(SongUpExecute, SongUpCanExecute); 
        } 
        <span class="kwrd">return</span> songUp; 
    }
}</pre>
<p>The RelayCommand is very well suited to the M-V-VM pattern because it allows me to encapsulate the whole command and its executing logic very cleanly in my ViewModel. The View can then just bind to these commands!</p>
<p>For more information about custom ICommand implementations, read <a href="http://dotnet.org.za/rudi/archive/2009/03/05/the-power-of-icommand.aspx">
The Power of ICommand</a></p>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h4><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/TurnThePage_2.gif"><img title="TurnThePage" border="0" alt="TurnThePage" align="right" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/TurnThePage_thumb.gif" width="300" height="240"></a>
 3D WPF Book Control</h4>
<blockquote>
<p><em>“The Great Library of Alexandria was founded in 300 B.C.E. with the grand objective of collecting the world's knowledge in one place; at its height, the library contained nearly 750,000 scrolls. In the modern world, the British Library contains one of
 the foremost collections; among its twenty million books and manuscripts are some of the rarest works in existence. It holds the Diamond Sutra, the oldest printed book; Mercator's first atlas of Europe; the Lindisfarne Gospels; Leonardo da Vinci's personal
 notebook; the Magna Carta; and the Codex Sinaiticus, one of the two earliest Christian Bibles. Such unique items must, of course, be treated with the utmost care. If they are on public display at all, they are well protected behind glass, and direct interaction
 is limited to a handful of individuals.</em></p>
<p><em>Happily, these works are now being digitized for the first time in order to reach a broad audience. Even better, the digitized versions are being turned into a rich interactive experience that adds curatorial content and brings the books to life. In
 collaboration with a UK-based software developer, the British Library developed a Windows®-based application called
<strong>Turning the Pages</strong> that offers a virtual facsimile in three-dimensional space of a growing number of the library's most precious items”</em></p>
</blockquote>
<p><a href="http://msdn.microsoft.com/en-us/magazine/cc163368.aspx">Turning the Pages with WPF by Tim Sneath</a></p>
<p>By using the free book control (released by <a href="http://blogs.msdn.com/mitsu">
Mitsuru Furuta</a> on <a href="http://www.codeplex.com/wpfbookcontrol/">CodePlex</a>), we will be transforming our WMP media library into a book browsing experience!</p>
<p>To use the controls, we need to reference the WPMMitsuControls.dll and add the following namespace</p>
<pre class="csharpcode">xmlns:controls=<span class="str">&quot;clr-namespace:WPFMitsuControls;assembly=WPFMitsuControls&quot;</span></pre>
<p>Because Book derive from ItemsControl, we can bind it to any collection using ItemsSource and change the ItemTemplate (Like we would using ListBox, ListView, etc)</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">controls:Book</span> <span class="attr">ItemsSource</span><span class="kwrd">=&quot;...&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">controls:Book.ItemTemplate</span><span class="kwrd">&gt;</span>
        ...
    <span class="kwrd">&lt;/</span><span class="html">controls:Book.ItemTemplate</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">controls:Book</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h4>Accessing the parallel port</h4>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/parallelPort1_4.png"><img title="parallelPort1" border="0" alt="parallelPort1" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/parallelPort1_thumb_1.png" width="523" height="234"></a>
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/parallelPortReg_4.png"><img title="parallelPortReg" border="0" alt="parallelPortReg" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/parallelPortReg_thumb_1.png" width="586" height="102"></a>
</p>
<p>We will be using the status register (Base &#43; 1) for feedback from the keypad. To access the keypad we need a hardware IO driver (I will be using inpout32.dll). inpout32.dll is a win32 dll so we need to p/invoke</p>
<p><strong>C#:</strong></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> PortAccess 
{ 
    [DllImport(<span class="str">&quot;inpout32.dll&quot;</span>, EntryPoint = <span class="str">&quot;Out32&quot;</span>)] 
    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">extern</span> <span class="kwrd">void</span> Output(<span class="kwrd">int</span> adress, <span class="kwrd">int</span> <span class="kwrd">value</span>); 
    
    [DllImport(<span class="str">&quot;inpout32.dll&quot;</span>, EntryPoint = <span class="str">&quot;Inp32&quot;</span>)] 
    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">extern</span> <span class="kwrd">int</span> Input(<span class="kwrd">int</span> adress); 
}</pre>
<p>For more information on how to access the LPT port using managed code, first read the following CodeProject article:</p>
<ul>
<li><a href="http://www.codeproject.com/KB/cs/csppleds.aspx">CodeProject: I/O Ports Uncensored - 1 - Controlling LEDs (Light Emiting Diodes) with Parallel Port</a>
</li></ul>
<h2>Electronics 101</h2>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/Schematic.jpg"><img title="Schematic" border="0" alt="Schematic" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/Schematic_thumb.jpg" width="350" height="160"></a>
</p>
<p>This is a very basic schematic of how my keypad is wired up...</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/Cable.jpg"><img title="Cable" border="0" alt="Cable" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/Cable_thumb.jpg" width="240" height="182"></a>
</p>
<p>I had a keypad laying round which I used but you can also use normal push buttons available at your local electronics shop (<a href="http://www.radioshack.com/search/index.jsp?kwCatId=&amp;kw=push%20button&amp;origkw=push%20button&amp;sr=1">Here</a> is a list of push
 buttons available from RadioShack)</p>
<h4>WindowWithKeypadSupport</h4>
<p>The last part we need to cover is how to react to a key being pressed on the keypad. I sub-classed the WPF Window and created my own WindowWithKeypadSupport. WindowWithKeypadSupport has a background thread running which monitors the LPT port. If a button
 is pressed, it raises a PreviewKeypadDown routed event.</p>
<p><strong>C#:</strong></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> WindowWithKeypadSupport : Window 
{ 
    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> RoutedEvent PreviewKeypadDownEvent; 
    
    <span class="kwrd">static</span> WindowWithKeypadSupport() 
    {
        WindowWithKeypadSupport.PreviewKeypadDownEvent = 
            EventManager.RegisterRoutedEvent( <span class="str">&quot;PreviewKeypadDown&quot;</span>, 
            RoutingStrategy.Bubble, <span class="kwrd">typeof</span>(KeypadEventHandler), 
            <span class="kwrd">typeof</span>(WindowWithKeypadSupport)); 
    } 
    
    <span class="kwrd">public</span> <span class="kwrd">event</span> RoutedEventHandler PreviewKeypadDown 
    { 
        add 
        { 
            <span class="kwrd">base</span>.AddHandler(WindowWithKeypadSupport.PreviewKeypadDownEvent, <span class="kwrd">value</span>); 
        }         
        remove 
        { 
            <span class="kwrd">base</span>.RemoveHandler(WindowWithKeypadSupport.PreviewKeypadDownEvent, <span class="kwrd">value</span>); 
        } 
    } 
    <span class="rem">// The rest of the class is omited for brevity </span>
} </pre>
<p>To raise the event, we need to invoke back to the UI thread</p>
<p><strong>C#:</strong></p>
<pre class="csharpcode">Dispatcher.BeginInvoke(DispatcherPriority.Background,
    (SendOrPostCallback)<span class="kwrd">delegate</span> 
    { 
        KeypadEventArgs e = <span class="kwrd">new</span> KeypadEventArgs(
            WindowWithKeypadSupport.PreviewKeypadDownEvent, <span class="kwrd">this</span>); 
        e.Key = CreateKeyFromIOPortValue(keyValue); 
        <span class="kwrd">base</span>.RaiseEvent(e); 
    }, <span class="kwrd">null</span>);</pre>
<p>Here is a example of how to instantiate the WindowWithKeyadSupport</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">controls:WindowWithKeypadSupport</span> <span class="attr">x:Class</span><span class="kwrd">=&quot;ClassicJukebox.MainWindow&quot;</span>
    <span class="attr">xmlns</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span>
    <span class="attr">xmlns:x</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span>
    <span class="attr">xmlns:controls</span><span class="kwrd">=&quot;clr-namespace:ClassicJukebox&quot;</span>
    <span class="attr">PreviewKeypadDown</span><span class="kwrd">=&quot;WindowWithKeypadSupport_PreviewKeypadDown&quot;</span> <span class="kwrd">/&gt;</span></pre>
<p><b>TIP</b> - I also react to keyboard buttons being pressed... Use the left, right, up, down and enter keys to control the jukebox</p>
<p>And thats it...</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/ClassicJukebox.jpg"><img title="ClassicJukebox" border="0" alt="ClassicJukebox" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582639/ClassicJukebox_thumb.jpg" width="240" height="180"></a>
</p>
<h2>Conclusion</h2>
<p>WPF provides a very powerful infrastructure for creating applications that can mix 3D &amp; hardware effortless! The binding architecture and command support allows for great separation of concerns!</p>
<p>And probably the most important advantage of WPF? It makes writing applications fun…</p>
<h4>About the author</h4>
<p>Rudi Grobler's main area of interest is development in the embedded space (his day-to-day job). In the last 10 years Rudi interfaced to various devices in the embedded space ranging from Graphic LCDs using parallel port, various bill acceptors, RoboHum,
 smart card readers, Wii remote, data acquisition devices, petrol pumps and much, much more!About 2 years ago, he received a copy of Charles Petzold's WPF book and fell in love…</p>
<p>His ramblings can be found at <a href="http://dotnet.org.za/rudi">http://dotnet.org.za/rudi</a></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Rudi-Grobler/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:1aaf2f10a1bf40f289e09e7600cc73a3">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Classic-JukeBox</comments>
      <itunes:summary>

 Remember the 
classic arcade style jukeboxes? Today we will be creating our own jukebox using WPF, WMP, a little bit of 3D, some very basic electronics (costing less than $10 USD) and a splash of M-V-VM 

Introduction
A couple of weeks ago I took my son to the game arcade to play a little… while playing, I noticed in the corner a old jukebox… I started wondering how difficult it would be to recreate one of these using “real” hardware and WPF? This article explorers how
 to make real hardware control software applications in a practical manner 
M-V-VM

“Once a developer becomes comfortable with WPF and MVVM, it can be difficult to differentiate the two. MVVM is the lingua franca of WPF developers because it is well suited to the WPF platform, and WPF was designed to make it easy to build applications
 using the MVVM pattern (amongst others). In fact, Microsoft was using MVVM internally to develop WPF applications, such as Microsoft Expression Blend, while the core WPF platform was under construction. Many aspects of WPF, such as the look-less control model
 and data templates, utilize the strong separation of display from state and behavior promoted by MVVM.” 

WPF Apps With The Model-View-ViewModel Design Pattern by Josh Smith 
The M-V-VM pattern helps to separate the logic from the UI which is VERY important when you actually want to manipulate the logic from external sources (Like real push buttons). Our MediaViewModel is extremely simple… 

 
The MediaViewModel has a collection of albums (Which gets fetched when Initialize() is called) and also exposes some commands 
Setting up Windows Media Player media library

 
Ensure that your Windows Media Player (WMP) media library has some media. I added a few albums to my library by clicking on the Add to library… menu option. 
TIP - I also ensured that all my CD&#39;s that I do add has full ID3 tags and album art 
Fetching WMP media library
To fetch the media library from WMP, we have to use a little bit of COM 

“Micros</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Classic-JukeBox</link>
      <pubDate>Tue, 19 May 2009 16:09:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Classic-JukeBox</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/9582639_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/9582639_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Rudi Grobler</dc:creator>
      <itunes:author>Rudi Grobler</itunes:author>
      <slash:comments>2</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Classic-JukeBox/RSS</wfw:commentRss>
    </item>    
</channel>
</rss>