<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-8093175187185319143</atom:id><lastBuildDate>Sun, 08 Sep 2024 08:15:45 +0000</lastBuildDate><category>MVVM</category><category>Zune</category><category>Animation</category><category>Threading</category><title>Gone Codin&#39;</title><description>I code now so I can fish later.</description><link>http://kewleyoncode.blogspot.com/</link><managingEditor>noreply@blogger.com (Josh)</managingEditor><generator>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8093175187185319143.post-4993903350779555953</guid><pubDate>Fri, 03 Sep 2010 23:23:00 +0000</pubDate><atom:updated>2010-09-08T17:46:13.658-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Animation</category><category domain="http://www.blogger.com/atom/ns#">MVVM</category><category domain="http://www.blogger.com/atom/ns#">Zune</category><title>Now Playing with MVVM – Animating cover transitions</title><description>&lt;blockquote&gt; &lt;p&gt;&lt;em&gt;This is part 6 of a series of posts in which I attempt to reproduce the Zune Now Playing interface using the MVVM pattern within WPF. An introduction to the series and table of contents can be found in the &lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/taking-wpf-for-ride-now-playing-with.html&quot;&gt;first post of this series&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The Zune Now Playing interface uses a subtle animation when transitioning from one album cover to another. To help me reproduce this effect I used Blend, which provides an intuitive interface for creating keyframe-based animations using storyboard or visual states. I’ve chosen to use storyboards, which I think will make my MVVM approach easier to implement because if won’t encourage me to rely on the VisualStateManager class, which is closely associated to the world of the view. &lt;/p&gt; &lt;p&gt;There are a &lt;a href=&quot;http://tdanemar.wordpress.com/2009/11/15/using-the-visualstatemanager-with-the-model-view-viewmodel-pattern-in-wpf-or-silverlight/&quot; target=&quot;_blank&quot;&gt;number of&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://chris.59north.com/post/mvvm-and-animations.aspx&quot; target=&quot;_blank&quot;&gt;documented approaches&lt;/a&gt; on the &lt;a href=&quot;http://blogs.msdn.com/b/erwinvandervalk/archive/2009/10/12/how-to-work-with-animations-in-silverlight-in-the-mvvm-pattern.aspx&quot; target=&quot;_blank&quot;&gt;Internet for how to handle&lt;/a&gt; &lt;a href=&quot;http://www.thejoyofcode.com/Model_View_ViewModel_and_Animation.aspx&quot; target=&quot;_blank&quot;&gt;animations when using the MVVM pattern&lt;/a&gt;. Some initially felt like complex implementations which put the purity of separation first, while others conceded to a small splash of code behind in the view. While the code-behind approach certainly appeals to me because it appears to offer an easier solution, I don’t want to go that way, because I’d rather focus on adhering to the guiding principles of the MVVM pattern. &lt;/p&gt; &lt;p&gt;Most of the suggestions only deal with kicking a single animation off, but what I’m after is more complex than that. When an Album is updated, I’ll start a fade out animation. Once the fade out completes, I’ll update the Album in the model and fire the view’s databinding updates via INotifyPropertyChanged. Finally, I’ll start a different animation to fade the album back in. With such interdependency between animations that occur in the view and state that is transitioning in the viewmodel, this quickly becomes a chicken-or-the-egg problem. I don’t want animation constructs in my viewmodel because the goal is to keep the project blendable, and to allow designers to tweak the animation in Blend.&lt;/p&gt; &lt;p&gt;My approach is similar to those that appear in some of the articles I’ve linked to above. I’ve ended up using a combination of an enum for the various states of the image transition process, a couple of data triggers, and a storyboard completed trigger. Here’s what the flow looks like:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://insario.com/media/cd4f9439f210_9B4B/MVVMAnimationFlow.gif&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;MVVMAnimationFlow&quot; border=&quot;0&quot; alt=&quot;MVVMAnimationFlow&quot; src=&quot;http://insario.com/media/cd4f9439f210_9B4B/MVVMAnimationFlow_thumb.gif&quot; width=&quot;462&quot; height=&quot;556&quot;&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Here’s how I’ve modified the CoverViewModel to accommodate the change. An external entity would call UpdateAlbum to start the process. &lt;/p&gt; &lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:7b8405c7-8d3b-4bf4-8ec3-801319e5d37a&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: csharp; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 671px;&quot; style=&quot; width: 900px; height: 671px;overflow: auto;&quot;&gt;&lt;br /&gt;namespace NowPlayingMVVM.ViewModel {&lt;br /&gt;  public enum ImageState {&lt;br /&gt;    New,&lt;br /&gt;    BeforeChange,&lt;br /&gt;    Changing,&lt;br /&gt;    AfterChange&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public class CoverViewModel : ViewModelBase, IAlbumConsumer {&lt;br /&gt;    private Album theAlbum;&lt;br /&gt;    private ImageState theImageState = ImageState.New;&lt;br /&gt;    ...&lt;br /&gt;    public ImageState ImageState {&lt;br /&gt;        get { return theImageState; }&lt;br /&gt;        set {&lt;br /&gt;            theImageState = value;&lt;br /&gt;            NotifyPropertyChanged(&amp;quot;ImageState&amp;quot;);&lt;br /&gt;            if(value == ImageState.Changing) {&lt;br /&gt;                NotifyPropertyChanged(&amp;quot;ArtworkUrl&amp;quot;);&lt;br /&gt;                NotifyPropertyChanged(&amp;quot;Name&amp;quot;);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;  &lt;br /&gt;    public void UpdateAlbum(Album anAlbum) {&lt;br /&gt;        if(theAlbum == anAlbum) return;&lt;br /&gt;        if (theAlbum == null) {&lt;br /&gt;            theAlbum = anAlbum;&lt;br /&gt;            ImageState = ImageState.Changing;&lt;br /&gt;        } else {&lt;br /&gt;            ImageState = ImageState.BeforeChange;&lt;br /&gt;            theAlbum = anAlbum;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;And on the View side&lt;/p&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:bdc0d49d-48f3-41a9-a7e6-335d2ae51c59&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: xml; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 435px;&quot; style=&quot; width: 900px; height: 435px;overflow: auto;&quot;&gt;&amp;lt;Image x:Name=&amp;quot;image&amp;quot; Source=&amp;quot;{Binding ArtworkUrl}&amp;quot; Stretch=&amp;quot;Fill&amp;quot; Width=&amp;quot;280&amp;quot; Height=&amp;quot;280&amp;quot; RenderTransformOrigin=&amp;quot;0.5,0.5&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;Interactivity:Interaction.Triggers&amp;gt;&lt;br /&gt;  	&amp;lt;ei:DataTrigger Binding=&amp;quot;{Binding ImageState}&amp;quot; Value=&amp;quot;BeforeChange&amp;quot;&amp;gt;&lt;br /&gt;			&amp;lt;!-- When ImageState becomes BeforeChange, fire FadeOut animation --&amp;gt;&lt;br /&gt;  		&amp;lt;ei:ControlStoryboardAction Storyboard=&amp;quot;{StaticResource FadeOut}&amp;quot;  /&amp;gt;&lt;br /&gt;  	&amp;lt;/ei:DataTrigger&amp;gt;&lt;br /&gt;    &amp;lt;ei:StoryboardCompletedTrigger Storyboard=&amp;quot;{StaticResource FadeOut}&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;!-- When FadeOut completes, update ImageState to Changing --&amp;gt;&lt;br /&gt;			&amp;lt;ei:ChangePropertyAction PropertyName=&amp;quot;ImageState&amp;quot; TargetObject=&amp;quot;{Binding}&amp;quot; Value=&amp;quot;Changing&amp;quot; /&amp;gt;&lt;br /&gt;  	&amp;lt;/ei:StoryboardCompletedTrigger&amp;gt;&lt;br /&gt;    &amp;lt;ei:DataTrigger Binding=&amp;quot;{Binding ImageState}&amp;quot; Value=&amp;quot;Changing&amp;quot;&amp;gt;&lt;br /&gt;  		&amp;lt;!-- When ImageState becomes Changing, fire FadeIn animation --&amp;gt;&lt;br /&gt;			&amp;lt;ei:ControlStoryboardAction Storyboard=&amp;quot;{StaticResource FadeIn}&amp;quot; /&amp;gt;&lt;br /&gt;  	&amp;lt;/ei:DataTrigger&amp;gt;&lt;br /&gt;    &amp;lt;ei:StoryboardCompletedTrigger Storyboard=&amp;quot;{StaticResource FadeIn}&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;!-- When FadeIn completes, update ImageState to AfterChange --&amp;gt;&lt;br /&gt;			&amp;lt;ei:ChangePropertyAction PropertyName=&amp;quot;ImageState&amp;quot; TargetObject=&amp;quot;{Binding}&amp;quot; Value=&amp;quot;AfterChange&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/ei:StoryboardCompletedTrigger&amp;gt;&lt;br /&gt;  &amp;lt;/Interactivity:Interaction.Triggers&amp;gt;&lt;br /&gt;&amp;lt;/Image&amp;gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;I don’t really love this approach because although it technically doesn’t require the View and ViewModel to know about each other, the two are still tightly bound by the use of the enum and the order of events. When looking at the ViewModel, the trigger logic can only really be understood with a good grasp of what is happening in the View. In addition, while the View still renders in Blend, the animations don’t fire, so I’m unable to test and refine them. Because I’m trying to create a common animation for each of my cover views, I’ve had to resort to creating a TestAnimation user control where I can use the tools to develop the animation I want, before copying the resource to my shared ResourceDictionary. Each of the cover views is a different size, so I can’t take advantage of FrameworkElement.Width, and I have to use RenderTransforms instead.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I wonder if my objections to this approach are petty and over-thought. This solution doesn’t feel right, but it will work for the time being. As I learn more about WPF, I’ll refine my understanding of what the pluses and minuses of this approach are.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://insario.com/mvvm/AlbumTransition.zip&quot; target=&quot;_blank&quot;&gt;Download Project&lt;/a&gt;&lt;/p&gt;  </description><link>http://kewleyoncode.blogspot.com/2010/09/now-playing-with-mvvm-animating-cover.html</link><author>noreply@blogger.com (Josh)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8093175187185319143.post-8267045664565868967</guid><pubDate>Fri, 20 Aug 2010 01:24:00 +0000</pubDate><atom:updated>2010-09-08T17:47:56.624-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Threading</category><title>Now Playing with MVVM – Fetching Sample Album / Artist / Song Data</title><description>&lt;blockquote&gt; &lt;p&gt;&lt;em&gt;This is part 5 of a series of posts in which I attempt to reproduce the Zune Now Playing interface using the MVVM pattern within WPF. An introduction to the series and table of contents can be found in the &lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/taking-wpf-for-ride-now-playing-with.html&quot;&gt;first post of this series&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;To this point in my &lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/taking-wpf-for-ride-now-playing-with.html&quot;&gt;Now Playing with MVVM series&lt;/a&gt; I’ve been relying on static sample data that I’ve hardcoded into my application. It served me well while I was just working with half a dozen album covers, but now that I’m getting closer to implementing an &lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/now-playing-with-mvvm-part-4.html&quot;&gt;interface that needs to stretch full screen&lt;/a&gt;, I’ll need data that is more dynamic and more interesting to look at.&lt;/p&gt; &lt;p&gt;I don’t use them myself, but a few of my friends and family use the &lt;a href=&quot;http://www.rhapsody.com/&quot; target=&quot;_blank&quot;&gt;Rhapsody&lt;/a&gt; service. Some &lt;a href=&quot;http://www.bing.com/&quot; target=&quot;_blank&quot;&gt;Bing&lt;/a&gt;ing lead me to &lt;a href=&quot;http://www.rhapsody.com/feeds.html&quot; target=&quot;_blank&quot;&gt;a page on the Rhapsody site&lt;/a&gt; where they offer up a selection of RSS and OPML feeds of top albums, artists, tracks, new releases, and more. This is a great solution for me, not only because of the amount and depth of data, but because by retrieving it over the Internet, I’ll be forced to deal with binding to data that is not immediately available.&lt;/p&gt; &lt;p&gt;The service I’ve chosen to work with is the &lt;a href=&quot;http://feeds.rhapsody.com/new-releases.rss&quot; target=&quot;_blank&quot;&gt;New Releases feed&lt;/a&gt;. This should be a good source of ever-changing data that pulls from a different genres and album types. If you click directly on &lt;a href=&quot;http://feeds.rhapsody.com/new-releases.rss&quot; target=&quot;_blank&quot;&gt;the feed URL&lt;/a&gt; with a browser, it will display a formatted web page by doing a client side XSL transform, so I used &lt;a href=&quot;http://www.ultraedit.com&quot; target=&quot;_blank&quot;&gt;UltraEdit&lt;/a&gt; to open the raw feed data to examine the RSS formatting.&lt;/p&gt; &lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:6298b3f0-e4d4-4f7d-9201-dd87e2355479&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: xml; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 500px;&quot; style=&quot; width: 900px; height: 500px;overflow: auto;&quot;&gt;&amp;lt;rss version=&amp;quot;2.0&amp;quot; xmlns:rhap=&amp;quot;http://feeds.rhapsody.com/dtds/&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;channel&amp;gt;&lt;br /&gt;    &amp;lt;title&amp;gt;New Releases on Rhapsody Online&amp;lt;/title&amp;gt;&lt;br /&gt;    &amp;lt;link&amp;gt;http://www.rhapsody.com?rws=%2Fnew-releases.rss&amp;lt;/link&amp;gt;&lt;br /&gt;    &amp;lt;description&amp;gt;New Releases on Rhapsody Online&amp;lt;/description&amp;gt;&lt;br /&gt;    &amp;lt;category /&amp;gt;&lt;br /&gt;    &amp;lt;language&amp;gt;en&amp;lt;/language&amp;gt;&lt;br /&gt;    &amp;lt;ttl&amp;gt;720&amp;lt;/ttl&amp;gt;&lt;br /&gt;    &amp;lt;pubDate&amp;gt;Thu, 19 Aug 2010 02:34:12 -0700&amp;lt;/pubDate&amp;gt;&lt;br /&gt;    &amp;lt;image&amp;gt;&lt;br /&gt;      &amp;lt;url&amp;gt;http://static.realone.com/rotw/images/logo_rhapsody_113x22.gif&amp;lt;/url&amp;gt;&lt;br /&gt;      &amp;lt;title&amp;gt;New Releases on Rhapsody Online&amp;lt;/title&amp;gt;&lt;br /&gt;      &amp;lt;link&amp;gt;http://www.rhapsody.com?rws=%2Fnew-releases.rss&amp;lt;/link&amp;gt;&lt;br /&gt;      &amp;lt;description&amp;gt;New Releases on Rhapsody Online&amp;lt;/description&amp;gt;&lt;br /&gt;    &amp;lt;/image&amp;gt;&lt;br /&gt;    &amp;lt;item&amp;gt;&lt;br /&gt;      &amp;lt;title&amp;gt;God Willin&#39; &amp;amp;amp; The Creek Don&#39;t Rise - Ray LaMontagne&amp;lt;/title&amp;gt;&lt;br /&gt;      &amp;lt;link&amp;gt;http://www.rhapsody.com/goto?rcid=alb.39896780&amp;amp;amp;variant=play&amp;amp;amp;rws=%2Fnew-releases.rss&amp;lt;/link&amp;gt;&lt;br /&gt;      &amp;lt;category&amp;gt;Adult Alternative&amp;lt;/category&amp;gt;&lt;br /&gt;      &amp;lt;pubDate&amp;gt;Tue, 17 Aug 2010 13:17:19 -0700&amp;lt;/pubDate&amp;gt;&lt;br /&gt;      &amp;lt;source url=&amp;quot;http://www.rhapsody.com?rws=%2Fnew-releases.rss&amp;quot;&amp;gt;New Releases on Rhapsody Online&amp;lt;/source&amp;gt;&lt;br /&gt;      &amp;lt;guid isPermaLink=&amp;quot;false&amp;quot;&amp;gt;alb.39896780&amp;lt;/guid&amp;gt;&lt;br /&gt;      &amp;lt;rhap:rcid xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;alb.39896780&amp;lt;/rhap:rcid&amp;gt;&lt;br /&gt;      &amp;lt;rhap:artist xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;Ray LaMontagne&amp;lt;/rhap:artist&amp;gt;&lt;br /&gt;      &amp;lt;rhap:artist-rcid xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;art.6479139&amp;lt;/rhap:artist-rcid&amp;gt;&lt;br /&gt;      &amp;lt;rhap:price xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;9.99&amp;lt;/rhap:price&amp;gt;&lt;br /&gt;      &amp;lt;rhap:album xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;God Willin&#39; &amp;amp;amp; The Creek Don&#39;t Rise&amp;lt;/rhap:album&amp;gt;&lt;br /&gt;      &amp;lt;rhap:album-rcid xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;alb.39896780&amp;lt;/rhap:album-rcid&amp;gt;&lt;br /&gt;      &amp;lt;rhap:album-art xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;http://image.listen.com/img/170x170/5/1/4/1/2081415_170x170.jpg&amp;lt;/rhap:album-art&amp;gt;&lt;br /&gt;      &amp;lt;rhap:album-release-date xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;2010-08-17 13:17:19.0&amp;lt;/rhap:album-release-date&amp;gt;&lt;br /&gt;      &amp;lt;rhap:album-original-release-date xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;2010-08-17 13:17:19.0&amp;lt;/rhap:album-original-release-date&amp;gt;&lt;br /&gt;      &amp;lt;rhap:album-is-available xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;true&amp;lt;/rhap:album-is-available&amp;gt;&lt;br /&gt;      &amp;lt;rhap:explicit xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;false&amp;lt;/rhap:explicit&amp;gt;&lt;br /&gt;      &amp;lt;rhap:album-type xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;main-release&amp;lt;/rhap:album-type&amp;gt;&lt;br /&gt;      &amp;lt;rhap:play-href xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;http://www.rhapsody.com/goto?rcid=alb.39896780&amp;amp;amp;variant=play&amp;amp;amp;rws=%2Fnew-releases.rss&amp;lt;/rhap:play-href&amp;gt;&lt;br /&gt;      &amp;lt;rhap:data-href xmlns:rhap=&amp;quot;rhap&amp;quot;&amp;gt;http://www.rhapsody.com/goto?rcid=alb.39896780&amp;amp;amp;variant=data&amp;amp;amp;rws=%2Fnew-releases.rss&amp;lt;/rhap:data-href&amp;gt;&lt;br /&gt;      &amp;lt;description&amp;gt;&lt;br /&gt;        &amp;lt;![CDATA[God Willin&#39; &amp;amp; The Creek Don&#39;t Rise - Ray LaMontagne]]&amp;gt;&lt;br /&gt;      &amp;lt;/description&amp;gt;&lt;br /&gt;    &amp;lt;/item&amp;gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;.Net 3.5 introduced the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb357210.aspx&quot; target=&quot;_blank&quot;&gt;System.ServiceModel.Syndication&lt;/a&gt; namespace which aids in the creation and parsing of RSS and ATOM feeds. This library will make the task of hydrating the Album/Artist/Song object model very easy. To get at the list of items in the feed, you load them from an XMLReader that you’ve passed the RSS URI to: &lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:e0aa9ea9-952a-4d25-ba1d-004e75aa273d&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: csharp; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 225px;&quot; style=&quot; width: 900px; height: 225px;overflow: auto;&quot;&gt;List&amp;lt;Album&amp;gt; Albums = null;&lt;br /&gt;Uri myFeedUri = new Uri(&amp;quot;http://feeds.rhapsody.com/new-releases.rss&amp;quot;); &lt;br /&gt;using(XmlReader myReader = XmlReader.Create(myFeedUri.AbsoluteUri)) {&lt;br /&gt;    SyndicationFeed myFeed = SyndicationFeed.Load(myReader);&lt;br /&gt;    if(myFeed != null) {&lt;br /&gt;        Albums = new List&amp;lt;Album&amp;gt;(myFeed.Items.Count());&lt;br /&gt;        foreach(SyndicationItem myItem in myFeed.Items) {&lt;br /&gt;          //work with the next item&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;The SyndicationItem entity makes the standard RSS elements available to the client, and it also provides a way to access vendor-specific element extensions. The Rhapsody feeds make album, artist, track, and other metadata available through a custom namespace as part of each SyndicationItem. SyndicationItem makes these additional elements available in a collection called ElementExtensions. There is a discussion of how to &lt;a href=&quot;http://stackoverflow.com/questions/319591/reading-non-standard-elements-in-a-syndicationitem-with-syndicationfeed&quot; target=&quot;_blank&quot;&gt;access these items on Stack Overflow&lt;/a&gt;. Here is how I grabbed the album art from the new releases feed shown above.&lt;/p&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:f4a9ed10-47a8-4816-9940-d17dd026cef6&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: csharp; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 243px;&quot; style=&quot; width: 900px; height: 243px;overflow: auto;&quot;&gt;foreach(SyndicationItem myItem in myFeed.Items) {&lt;br /&gt;  Album anAlbum = new Album&lt;br /&gt;      {&lt;br /&gt;          ID = myItem.Id,&lt;br /&gt;          Name = myItem.Title.Text,&lt;br /&gt;          Category = myItem.Categories[0].Name,&lt;br /&gt;          ArtworkUrl = myItem.ElementExtensions.First(&lt;br /&gt;                albumext =&amp;gt; albumext.OuterNamespace == &amp;quot;rhap&amp;quot; &amp;amp;&amp;amp; &lt;br /&gt;                albumext.OuterName == &amp;quot;album-art&amp;quot;)&lt;br /&gt;              .GetObject&amp;lt;string&amp;gt;()&lt;br /&gt;      };&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;I qualified the OuterNamespace as a precaution against some unforeseen change in the feed where another element with the name “album-art” is introduced into a different namespace inside each item. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;I’d also like to build the track list for each album while hydrating them from the new releases feed. Rhapsody offers this capability by accessing the following URI: http://www.rhapsody.com/goto?rcid=&amp;lt;rhap:rcid&amp;gt;&amp;amp;variant=rss-feed. This makes fetching the song metadata a snap:&lt;/p&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:e81154bf-cef4-49a9-a958-cc4d62b314ea&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: csharp; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 585px;&quot; style=&quot; width: 900px; height: 585px;overflow: auto;&quot;&gt;foreach(SyndicationItem myItem in myFeed.Items) {&lt;br /&gt;  Album anAlbum = new Album&lt;br /&gt;      {&lt;br /&gt;          ID = myItem.Id,&lt;br /&gt;          Name = myItem.Title.Text,&lt;br /&gt;          Category = myItem.Categories[0].Name,&lt;br /&gt;          ArtworkUrl = myItem.ElementExtensions.First(&lt;br /&gt;                albumext =&amp;gt; albumext.OuterNamespace == &amp;quot;rhap&amp;quot; &amp;amp;&amp;amp; &lt;br /&gt;                albumext.OuterName == &amp;quot;album-art&amp;quot;)&lt;br /&gt;              .GetObject&amp;lt;string&amp;gt;()&lt;br /&gt;      };&lt;br /&gt;  anAlbum.Songs = GetSongsForAlbum(anAlbum);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private List&amp;lt;Song&amp;gt; GetSongsForAlbum(Album aParentAlbum) {&lt;br /&gt;    List&amp;lt;Song&amp;gt; Songs = null;&lt;br /&gt;    string rssURL = string.Format(&amp;quot;http://www.rhapsody.com/goto?rcid={0}&amp;amp;variant=rss-feed&amp;quot;, aParentAlbum.ID);&lt;br /&gt;    Uri myFeedUri = new Uri(rssURL);&lt;br /&gt;    using(XmlReader myReader = XmlReader.Create(myFeedUri.AbsoluteUri)) {&lt;br /&gt;        SyndicationFeed myFeed = SyndicationFeed.Load(myReader);&lt;br /&gt;        if(myFeed != null) {&lt;br /&gt;            Songs = new List&amp;lt;Song&amp;gt;(myFeed.Items.Count());&lt;br /&gt;            foreach(SyndicationItem myItem in myFeed.Items) {&lt;br /&gt;                Song aSong = new Song&lt;br /&gt;                     {&lt;br /&gt;                         Album = aParentAlbum,&lt;br /&gt;                         Artist = aParentAlbum.Artist,&lt;br /&gt;                         Name = myItem.ElementExtensions.First(&lt;br /&gt;                            songext =&amp;gt; songext.OuterNamespace == &amp;quot;rhap&amp;quot; &amp;amp;&amp;amp; &lt;br /&gt;                            songext.OuterName == &amp;quot;track&amp;quot;)&lt;br /&gt;                          .GetObject&amp;lt;string&amp;gt;()&lt;br /&gt;                     };&lt;br /&gt;                Songs.Add(aSong);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    return Songs;&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;h2&gt;Speeding things up&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;This does the job just fine, but there’s a problem. At the time of this writing, the new releases feed has 144 items in it, meaning that 145 separate HTTP calls are required in order to load the whole media graph. This can be very slow because the requests are made sequentially on the same thread. Let’s introduce a little parallelism into this process.&lt;strong&gt;[NOTE: See update below. This code is not thread safe]&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:7df511cc-ab88-4a6d-9643-421bb32f5d6f&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: csharp; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 394px;&quot; style=&quot; width: 900px; height: 394px;overflow: auto;&quot;&gt;using(XmlReader myReader = XmlReader.Create(myFeedUri.AbsoluteUri)) {&lt;br /&gt;  SyndicationFeed myFeed = SyndicationFeed.Load(myReader);&lt;br /&gt;  if(myFeed != null) {&lt;br /&gt;    Albums = new List&amp;lt;Album&amp;gt;(myFeed.Items.Count());&lt;br /&gt;    //foreach(SyndicationItem myItem in myFeed.Items) &lt;br /&gt;    Parallel.ForEach(myFeed.Items, myItem =&amp;gt; {&lt;br /&gt;      Album anAlbum = new Album {&lt;br /&gt;          ID = myItem.Id,&lt;br /&gt;          Name = myItem.Title.Text,&lt;br /&gt;          Category = myItem.Categories[0].Name,&lt;br /&gt;          Artist = new Artist {&lt;br /&gt;            ID = &amp;lt;snip/&amp;gt;,&lt;br /&gt;            Name = &amp;lt;snip/&amp;gt;&lt;br /&gt;          },&lt;br /&gt;          ArtworkUrl = &amp;lt;snip/&amp;gt;&lt;br /&gt;      };&lt;br /&gt;      anAlbum.Songs = GetSongsForAlbum(anAlbum);&lt;br /&gt;    });&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Ok, much better. By taking advantage of the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd537608.aspx&quot; target=&quot;_blank&quot;&gt;Parallel tasks&lt;/a&gt; library in &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.aspx&quot; target=&quot;_blank&quot;&gt;System.Threading.Tasks.Parallel&lt;/a&gt;, I’ve cut the load time in half on my development box. But I think I can do better. What if I load the songs collection for each album on a background thread? &lt;strong&gt;[NOTE: See update below. This code is not thread safe]&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:66446f13-bd2f-4950-a3a4-996d4e805e0b&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: csharp; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 377px;&quot; style=&quot; width: 900px; height: 377px;overflow: auto;&quot;&gt;Albums = new List&amp;lt;Album&amp;gt;(myFeed.Items.Count());&lt;br /&gt;Parallel.ForEach(myFeed.Items, myItem =&amp;gt; {&lt;br /&gt;       Album anAlbum = new Album&lt;br /&gt;                           {&lt;br /&gt;                               ID = myItem.Id,&lt;br /&gt;                               Name = myItem.Title.Text,&lt;br /&gt;                               Category = myItem.Categories[0].Name,&lt;br /&gt;                               Artist = &amp;lt;snip/&amp;gt;&lt;br /&gt;                               ArtworkUrl = &amp;lt;snip/&amp;gt;&lt;br /&gt;                           };&lt;br /&gt;       BackgroundWorker aWorker = new BackgroundWorker();&lt;br /&gt;       aWorker.DoWork += (aSender, e) =&amp;gt; {&lt;br /&gt;             Album myAlbum = e.Argument as Album;&lt;br /&gt;             if(myAlbum != null)&lt;br /&gt;                 myAlbum.Songs = GetSongsForAlbum(anAlbum);&lt;br /&gt;         };&lt;br /&gt;       aWorker.RunWorkerAsync(anAlbum);&lt;br /&gt;       Albums.Add(anAlbum);&lt;br /&gt;   });&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Wow, much better. The albums collection is returned almost immediately and the songs fill themselves in on a background thread. This is exactly the sort of experience I expect from a WPF application.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: While integrating this code back into the Now Playing application, I found that my Parallel.ForEach loop was not returning. After some research, I determined it was caused by concurrent access to the List&amp;lt;Album&amp;gt;, which is not thread safe. The good news is that the .Net framework 4.0 includes a &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd287191.aspx&quot; target=&quot;_blank&quot;&gt;ConcurrentDictionary&lt;/a&gt; class, which lends itself well to my use case. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://insario.com/mvvm/AlbumLoading.zip&quot; target=&quot;_blank&quot;&gt;Download Project&lt;/a&gt;&lt;/p&gt;  </description><link>http://kewleyoncode.blogspot.com/2010/08/fetching-sample-album-artist-song-data.html</link><author>noreply@blogger.com (Josh)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8093175187185319143.post-7542488280861511235</guid><pubDate>Thu, 19 Aug 2010 23:21:00 +0000</pubDate><atom:updated>2010-09-09T10:29:51.015-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">MVVM</category><category domain="http://www.blogger.com/atom/ns#">Zune</category><title>Now Playing with MVVM – Replicating the Zune Now Playing layout</title><description>&lt;blockquote&gt; &lt;p&gt;&lt;em&gt;This is part 4 of a series of posts in which I attempt to reproduce the Zune Now Playing interface using the MVVM pattern within WPF. An introduction to the series and table of contents can be found in the &lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/taking-wpf-for-ride-now-playing-with.html&quot;&gt;first post of this series&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;In the previous postings I’ve assembled the infrastructure (however simplistic) that will help me reconstruct the Zune Now Playing interface. The plumbing I have in place so far has a lot of shortcomings, but I’m ready to put them behind me for now and focus on the layout for a bit. So the first order of business is to analyze the Zune software to see how they organize the covers. There is a pattern to the layout, which I’ve outlined below.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://insario.com/media/307cdf9eda0a_AA13/ZuneNowPlayingTemplateTrace.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;ZuneNowPlayingTemplateTrace&quot; border=&quot;0&quot; alt=&quot;ZuneNowPlayingTemplateTrace&quot; src=&quot;http://insario.com/media/307cdf9eda0a_AA13/ZuneNowPlayingTemplateTrace_thumb.jpg&quot; width=&quot;904&quot; height=&quot;490&quot;&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;As you can see, the interface is made up of a collection of templates that overlap, giving it a random feel. With this information, I can lay out the interface by creating a new view that hosts 49 individual cover views of varying sizes. &lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://insario.com/media/307cdf9eda0a_AA13/ZuneTemplateSkeleton.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;ZuneTemplateSkeleton&quot; border=&quot;0&quot; alt=&quot;ZuneTemplateSkeleton&quot; src=&quot;http://insario.com/media/307cdf9eda0a_AA13/ZuneTemplateSkeleton_thumb.jpg&quot; width=&quot;672&quot; height=&quot;526&quot;&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;These cover views are arranged in a parent grid by setting the margins for each one individually.&lt;/p&gt; &lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:d5526684-a849-4310-b55d-580df75c33c1&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: xml; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 191px;&quot; style=&quot; width: 900px; height: 191px;overflow: auto;&quot;&gt;&amp;lt;Grid x:Name=&amp;quot;LayoutRoot&amp;quot;&amp;gt;&lt;br /&gt; &amp;lt;Views:LargeCover    Margin=&amp;quot;0,0,0,0&amp;quot;      /&amp;gt;&lt;br /&gt; &amp;lt;Views:SmallCover    Margin=&amp;quot;0,280,0,0&amp;quot;    /&amp;gt;&lt;br /&gt; &amp;lt;Views:SmallCover    Margin=&amp;quot;70,280,0,0&amp;quot;   /&amp;gt;&lt;br /&gt; &amp;lt;Views:SmallCover    Margin=&amp;quot;140,280,0,0&amp;quot;  /&amp;gt;&lt;br /&gt; &amp;lt;Views:SmallCover    Margin=&amp;quot;210,280,0,0&amp;quot;  /&amp;gt;&lt;br /&gt; &amp;lt;Views:SmallCover    Margin=&amp;quot;0,350,0,0&amp;quot;    /&amp;gt;&lt;br /&gt; &amp;lt;Views:SmallCover    Margin=&amp;quot;70,350,0,0&amp;quot;   /&amp;gt;&lt;br /&gt; ...&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;The interface is still Blendable, which gives me the opportunity to see how the albums line up.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://insario.com/media/307cdf9eda0a_AA13/BlendableCoverTemplate.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;BlendableCoverTemplate&quot; border=&quot;0&quot; alt=&quot;BlendableCoverTemplate&quot; src=&quot;http://insario.com/media/307cdf9eda0a_AA13/BlendableCoverTemplate_thumb.jpg&quot; width=&quot;603&quot; height=&quot;484&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;To get a better feel for how the templates are going to come together, I can replace the covers on the MainWindow from previous postings with a couple of these new CoverTemplateViews. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://insario.com/media/307cdf9eda0a_AA13/MainWindowTemplated.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;MainWindowTemplated&quot; border=&quot;0&quot; alt=&quot;MainWindowTemplated&quot; src=&quot;http://insario.com/media/307cdf9eda0a_AA13/MainWindowTemplated_thumb.jpg&quot; width=&quot;904&quot; height=&quot;394&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;Sweet. The UI is beginning to take shape, but it also creates a few //TODO items for me.&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Now that I’m working with larger surface areas, I’ll need some more sample data. I need to be sure that the covers are evenly distributed and changed randomly. I’d also like to introduce song data into the model for future use. &lt;br /&gt;&lt;li&gt;The Zune software is resizable, and allows the user to maximize to a single monitor. Since I won’t know the end user’s screen resolution ahead of time, I’ll need to dynamically assemble these CoverTemplateViews inside a host container at runtime. &lt;br /&gt;&lt;li&gt;The cover transitions in the Zune software are smooth and buttery. I need to work on the transition animations for my implementation. &lt;br /&gt;&lt;li&gt;The Zune software has a nice looking overlay that tints the covers. The overlay is radial, and moves around a bit.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://insario.com/mvvm/NowPlayingMVVM-Part4.zip&quot; target=&quot;_blank&quot;&gt;Download Project&lt;/a&gt;&lt;/p&gt;  </description><link>http://kewleyoncode.blogspot.com/2010/08/now-playing-with-mvvm-part-4.html</link><author>noreply@blogger.com (Josh)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8093175187185319143.post-3268231552352447820</guid><pubDate>Sat, 14 Aug 2010 01:15:00 +0000</pubDate><atom:updated>2010-09-08T17:53:29.318-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">MVVM</category><title>Now Playing with MVVM – Separating View Models and Services</title><description>&lt;blockquote&gt; &lt;p&gt;&lt;em&gt;This is part 3 of a series of posts in which I attempt to reproduce the Zune Now Playing interface using the MVVM pattern within WPF. An introduction to the series and table of contents can be found in the &lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/taking-wpf-for-ride-now-playing-with.html&quot; target=&quot;_blank&quot;&gt;first post of this series&lt;/a&gt;.&lt;/em&gt;&lt;br&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;In the &lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/now-playing-with-mvvm-part-2.html&quot;&gt;previous post&lt;/a&gt;, I quickly threw together an interface that combined a number of album cover views into a parent grid. The datacontext for each view was bound directly to an Album entity that I created in a parent viewmodel. While this was enough to render the interface I was after, it suffered from a few shortcomings:&lt;br&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The cover views were directly bound to domain entities pulled out of an ObservableCollection by index, rather than viewmodels with bindable properties. This is bad design, and it bypasses the usefulness of ObservableCollection.  &lt;li&gt;I manually created the list of Albums in the MainPageViewModel. This should really be pulled out to a service so that I can fetch Albums from other sources and make them available to any viewmodels in my application that require them  &lt;li&gt;The covers were static – they did not change, and there was no accommodation for allowing them to update.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I need to clean this up a bit before I start worrying about the Zune layout. Let’s approach these concerns one at a time.&lt;/p&gt; &lt;h2&gt;Binding cover views to viewmodels&lt;/h2&gt; &lt;p&gt;To bring this application more in line with the MVVM approach, I want the cover views to use a CoverViewModel as their datacontext. My first step is to create a CoverViewModel class that exposes some of the Album attributes.&lt;br&gt;&lt;/p&gt; &lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:178568ad-ff89-4222-a3ae-053dcffe37fb&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: csharp; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 222px;&quot; style=&quot; width: 900px; height: 222px;overflow: auto;&quot;&gt;public class CoverViewModel : ViewModelBase {&lt;br /&gt;  private Album theAlbum;&lt;br /&gt;&lt;br /&gt;  public string ArtworkUrl { get { return Album.ArtworkUrl; } }&lt;br /&gt;  public string Name { get { return Album.Name; } }&lt;br /&gt;  public Album Album { get { return theAlbum; } set {&lt;br /&gt;      theAlbum = value; &lt;br /&gt;      NotifyPropertyChanged(&amp;quot;ArtworkUrl&amp;quot;); &lt;br /&gt;      NotifyPropertyChanged(&amp;quot;Name&amp;quot;);&lt;br /&gt;  } }&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;And now I can use a CoverViewModel in my cover views. At first glance, I figured this would be easy – just add a resource in each of the three cover views, and set the datacontext of the container grid to bind to the resource. You know, something like this:&lt;br&gt;&lt;/p&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:1ecda6c2-8eb2-4344-9c1e-bc13e204b332&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: xml; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  highlight: 2,3 ; width: 900px; height: 126px;&quot; style=&quot; width: 900px; height: 126px;overflow: auto;&quot;&gt;&amp;lt;UserControl.Resources&amp;gt;&lt;br /&gt;    &amp;lt;ViewModel:CoverViewModel x:Key=&amp;quot;CVM&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/UserControl.Resources&amp;gt;&lt;br /&gt;&amp;lt;Grid DataContext=&amp;quot;{Binding Source={StaticResource CVM}}&amp;quot; &amp;gt;&lt;br /&gt;    &amp;lt;Image Source=&amp;quot;{Binding Path=ArtworkUrl}&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;Label Content=&amp;quot;{Binding Path=Name}&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/Grid&amp;gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;This would appear to be just what I’m after, but binding declaratively like this introduces another problem - how will I hand each individual instance of the Cover a unique Album? This design is incomplete because it only addresses the pull portion of the binding – it makes no accommodation for setting the Album in the CoverViewModel before it binds to the ArtworkUrl and Name properties. I need a way to package up an Album and a CoverViewModel and hand it off to a cover view when assembling my main window. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;If I take a look at where I want to end up, I begin to see that there will need to be some master entity that maintains a list of bound CoverViewModels and available Albums. This entity will essentially do inventory management for the application – ensuring a high degree of ordered randomness in Album binding, and satisfying business rules around differing number of Albums and CoverViewModels. This leads me to my second point of consideration – how do I collect and store Album instances it in such a way that these binding and assembly issues will be resolved?&lt;br&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;collection storage VERSUS CONSUMPTION&lt;/h2&gt;Now that I’ve introduced a CoverViewModel layer between the Album and the view, the view and Album should no longer be aware of each other. Instead, I’ll create a service in my application that is responsible for discovering a list of Albums and making them available to outside entities that wish to use them. The service will be a provider of Albums, and will work with some yet-unknown classes that will be consumers of Albums. I think I’ll break the two into separate interfaces – IAlbumConsumer and IAlbumProvider.&lt;br&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:72ec69bc-4b69-4800-87e8-885a47109ffd&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: csharp; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 153px;&quot; style=&quot; width: 900px; height: 153px;overflow: auto;&quot;&gt;public interface IAlbumProvider {&lt;br /&gt;    void Register(IAlbumConsumer anAlbumConsumer);&lt;br /&gt;    void RefreshAlbum(IAlbumConsumer anAlbumConsumer);&lt;br /&gt;}&lt;br /&gt;public interface IAlbumConsumer {&lt;br /&gt;    void UpdateAlbum(Album anAlbum);&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;IAlbumConsumers will register with IAlbumProviders, who will provide them with Albums when requested. I’ve added a method for IAlbumProviders to push an update to individual IAlbumConsumers, as well as a way for an IAlbumConsumer to call in to to an IAlbumProvider and ask for a refresh. &lt;br&gt;I’ll move all of that manual Album creation code from &lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/now-playing-with-mvvm-part-2.html&quot;&gt;the last post&lt;/a&gt; out of the MainWindowViewModel and into a separate class. The new StaticAlbumProvider will implement the IAlbumProvider interface, and will maintain a list of available albums, along with a list of registered IAlbumConsumers. A static singleton property gives us a single point of storage for Album data across multiple viewmodel instances. Relevant code follows:&lt;br&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:3a26265d-533d-4caf-80b3-4ee98807fba9&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: csharp; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 541px;&quot; style=&quot; width: 900px; height: 541px;overflow: auto;&quot;&gt;internal class StaticAlbumProvider : IAlbumProvider {&lt;br /&gt;    private readonly Dictionary&amp;lt;Album, int&amp;gt; theAlbums = new Dictionary&amp;lt;Album, int&amp;gt;();&lt;br /&gt;    private readonly List&amp;lt;IAlbumConsumer&amp;gt; theViewModels = new List&amp;lt;IAlbumConsumer&amp;gt;();&lt;br /&gt;    internal static readonly IAlbumProvider Instance = new StaticAlbumProvider();&lt;br /&gt;&lt;br /&gt;    public StaticAlbumProvider() {&lt;br /&gt;        theAlbums.Add(new Album&lt;br /&gt;                          {&lt;br /&gt;                              Name = &amp;quot;Waking Up&amp;quot;,&lt;br /&gt;                              Artist = new Artist {Name = &amp;quot;OneRepublic&amp;quot;},&lt;br /&gt;                              ArtworkUrl = &amp;quot;http://image.listen.com/something.jpg&amp;quot;&lt;br /&gt;                          }, 0);  // counts how many times cover has been used in UI&lt;br /&gt;        //add more albums here		&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void Register(IAlbumConsumer aCoverViewModel) {&lt;br /&gt;        theViewModels.Add(aCoverViewModel);&lt;br /&gt;        aCoverViewModel.UpdateAlbum(GetNextRandomAlbum());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void RefreshAlbum(IAlbumConsumer anAlbumConsumer) {&lt;br /&gt;        anAlbumConsumer.UpdateAlbum(GetNextRandomAlbum());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private Album GetNextRandomAlbum() {&lt;br /&gt;        //random Album retrieval from theAlbums&lt;br /&gt;        return anAlbum;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;Implementing the IAlbumConsumer interface on CoverViewModel is straight forward. Note how a CoverViewModel registers itself upon creation with the StaticAlbumProvider instance. When it does so, the StaticAlbumProvider calls back into the CoverViewModel UpdateAlbum method, handing the viewmodel the album it needs:&lt;br&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:fd83a9f7-296e-44a6-82fb-3b17b26f1ade&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: csharp; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 296px;&quot; style=&quot; width: 900px; height: 296px;overflow: auto;&quot;&gt;public class CoverViewModel : ViewModelBase, IAlbumConsumer {&lt;br /&gt;    private Album theAlbum;&lt;br /&gt;    &lt;br /&gt;    public CoverViewModel() {&lt;br /&gt;        StaticAlbumProvider.Instance.Register(this);&lt;br /&gt;    }&lt;br /&gt;		&lt;br /&gt;    public string ArtworkUrl { get { return theAlbum.ArtworkUrl; } }&lt;br /&gt;    public string Name { get { return theAlbum.Name; } }&lt;br /&gt;&lt;br /&gt;    public void UpdateAlbum(Album anAlbum) {&lt;br /&gt;        theAlbum = anAlbum;&lt;br /&gt;        NotifyPropertyChanged(&amp;quot;ArtworkUrl&amp;quot;);&lt;br /&gt;        NotifyPropertyChanged(&amp;quot;Name&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;bringing together our views and viewmodels&lt;/h2&gt;The next step is to figure out a way to hand views different instances of the viewmodels. In a future post I’ll talk about View Model Locators, but for now I’ll take the same shortcut that I took with the StaticAlbumProvider. A simple ViewModelLocator class…&lt;br&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:94acab91-f6ed-420b-9866-5c21727863a7&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: csharp; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 94px;&quot; style=&quot; width: 900px; height: 94px;overflow: auto;&quot;&gt;public class ViewModelLocator {&lt;br /&gt;    public static readonly ViewModelLocator Instance = new ViewModelLocator();&lt;br /&gt;    public IAlbumConsumer CoverViewModel { get { return new CoverViewModel(); } }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;…allows me to put a keyed resource in a project-wide resource dictionary…&lt;br&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:d5d20e12-c858-42be-a4fe-1495fa537726&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: xml; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 117px;&quot; style=&quot; width: 900px; height: 117px;overflow: auto;&quot;&gt;&amp;lt;ResourceDictionary xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;br /&gt;                    xmlns:x=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot; &lt;br /&gt;                    xmlns:svc=&amp;quot;clr-namespace:NowPlayingMVVM.Service&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;svc:ViewModelLocator x:Key=&amp;quot;Locator&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/ResourceDictionary&amp;gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;…and bind to that resource by key name inside my CoverViewModels…&lt;br&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:1350b564-e1ac-44ae-a349-5025fde18c08&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: xml; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 149px;&quot; style=&quot; width: 900px; height: 149px;overflow: auto;&quot;&gt;&amp;lt;UserControl.Resources&amp;gt;&lt;br /&gt;    &amp;lt;ResourceDictionary Source=&amp;quot;../Resources.xaml&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/UserControl.Resources&amp;gt;&lt;br /&gt;&amp;lt;Grid DataContext=&amp;quot;{Binding Source={StaticResource Locator}, Path=CoverViewModel}&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;Image Source=&amp;quot;{Binding Path=ArtworkUrl}&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;Label Content=&amp;quot;{Binding Path=Name}&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/Grid&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;…providing context for the binding directives inside the viewmodel. Using a static resource retains the blendability of the cover viewmodels, meaning the album art will render in design view within Visual Studio or Blend.&lt;br&gt;&lt;a href=&quot;http://insario.com/media/ee5e19dc7452_EBD9/CoverViewArt.jpg&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;CoverViewArt&quot; border=&quot;0&quot; alt=&quot;CoverViewArt&quot; src=&quot;http://insario.com/media/ee5e19dc7452_EBD9/CoverViewArt_thumb.jpg&quot; width=&quot;324&quot; height=&quot;311&quot;&gt;&lt;/a&gt;&lt;br&gt;&lt;br /&gt;&lt;h2&gt;&amp;nbsp;&lt;/h2&gt;&lt;br /&gt;&lt;h2&gt;Rotating the collection&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;My last challenge for now is to tackle the problem that the album cover art is static and doesn’t rotate like the Zune Now Playing interface does. The way I constructed my IAlbumConsumer and IAlbumProvider interfaces allows me to force the update from either side of their relationship. It seems to make the most sense to me to drive the updates from the StaticAlbumProvider class, since this is where I’ll eventually keep track of which albums have been bound to the UI, and how many instances of that Album are currently showing. &lt;br&gt;&lt;/p&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:9D7513F9-C04C-4721-824A-2B34F0212519:0ac6fcd1-6b4d-4572-adf1-197cedcc1062&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;pre class=&quot;brush: csharp; gutter: true; first-line: 1; tab-size: 2;  toolbar: true;  width: 900px; height: 227px;&quot; style=&quot; width: 900px; height: 227px;overflow: auto;&quot;&gt;private void RefreshAnAlbum() {&lt;br /&gt;    theRefreshTimer = new Timer {&lt;br /&gt;                                    Interval = (new Random().Next(5) + 1) * 1000,&lt;br /&gt;                                    AutoReset = true&lt;br /&gt;                                };&lt;br /&gt;    theRefreshTimer.Elapsed += delegate { &lt;br /&gt;        theViewModels[new Random().Next(theViewModels.Count)].UpdateAlbum(GetNextRandomAlbum()); &lt;br /&gt;    };&lt;br /&gt;    theRefreshTimer.Start();&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;With this change, the covers rotate every few seconds, even on the design surface.&lt;br&gt;&lt;a href=&quot;http://insario.com/media/ee5e19dc7452_EBD9/CoverArrayWithArt.jpg&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;CoverArrayWithArt&quot; border=&quot;0&quot; alt=&quot;CoverArrayWithArt&quot; src=&quot;http://insario.com/media/ee5e19dc7452_EBD9/CoverArrayWithArt_thumb.jpg&quot; width=&quot;543&quot; height=&quot;347&quot;&gt;&lt;/a&gt;&lt;br&gt;Ok, so at this point I feel like I’ve got enough code in place to begin attacking the layout issues of my original goal – duplicating the Zune Now Playing interface. After I have that worked out, I’ll return to this design and look at introducing some existing frameworks to replace my custom viewmodel-related code. &lt;br&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://insario.com/mvvm/NowPlayingMVVM-Part3.zip&quot; target=&quot;_blank&quot;&gt;Download Project&lt;/a&gt;&lt;/p&gt;  </description><link>http://kewleyoncode.blogspot.com/2010/08/now-playing-with-mvvm-part-3.html</link><author>noreply@blogger.com (Josh)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8093175187185319143.post-526329576005810680</guid><pubDate>Fri, 06 Aug 2010 01:30:00 +0000</pubDate><atom:updated>2010-09-09T10:30:55.016-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">MVVM</category><title>Now Playing with MVVM - Getting Started: M-V-VM breakdown</title><description>&lt;blockquote&gt; &lt;p class=&quot;seriesintro&quot;&gt;&lt;em&gt;This is part 2 of a series of posts in which I attempt to reproduce the Zune Now Playing interface using the MVVM pattern within WPF. An introduction to the series and table of contents can be found in the &lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/taking-wpf-for-ride-now-playing-with.html&quot; target=&quot;_blank&quot;&gt;first post of this series&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;div class=&quot;seriesintro&quot;&gt;When broken down to its most basic elements, the Zune Now Playing interface is a collection of album art images of varying sizes, arranged in a particular order. In order to replicate the UI, my first step will be to try to look at the interface through MVVM goggles. How can I break it down into a domain model, a view template, and a mapping layer between the two?&lt;br&gt;&lt;br&gt;&lt;strong&gt;Model: &lt;/strong&gt;The domain revolves around Albums, Artists, and Songs. I have already done some &lt;a href=&quot;http://wiredright.wordpress.com/&quot; target=&quot;_blank&quot;&gt;domain modeling with this same set of resources&lt;/a&gt;, so I’ll borrow existing plumbing from that. I’ll also need a worker to go out and fetch the album data from an external resource. &lt;br&gt;&lt;strong&gt;&lt;br&gt;View: &lt;/strong&gt;The Zune Now Playing interface is built from a collection of three different sized user controls. I’ll create small, medium, and large cover views and arrange them in a parent container view that will allow me to lay them out the same way that the Zune software does. &lt;br&gt;&lt;strong&gt;&lt;br&gt;ViewModel: &lt;/strong&gt;The three cover views will bind to a common cover viewmodel which will represent the properties associated to an album, and the parent view will bind to a viewmodel that maintains the master list of all available albums. In addition to the bindable properties, the parent viewmodel will also be responsible for randomizing the album collection, reducing the number of duplicate covers, and ensuring that all covers have something to bind to regardless of the number of available albums. The parent viewmodel will also be responsible for shuffling album covers on the UI by kicking off animations that transition from one cover to the next.&lt;/div&gt; &lt;h1&gt;Quick Implementation&lt;/h1&gt;I’d like to quickly get something up and running to familiarize myself with the WPF binding infrastructure, so for now I’ll just jump in and start coding. I’ll start by creating three user controls – one for each of the three sizes of covers that are found in the Now Playing UI. The album cover views contain mostly the same XAML, the most notable difference being the size of the container. A grid serves as the parent object for Image and Label entities, which are bound to properties on the corresponding DataContext, which for now will be an Album.&amp;nbsp; &lt;br&gt;&lt;br&gt; &lt;div class=&quot;csharpcode&quot;&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Grid&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;x:Name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;LayoutRoot&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Width&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;280&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Height&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;280&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Background&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Red&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Image&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Source&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;{Binding Path=ArtworkUrl}&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Stretch&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Fill&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Width&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;280&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Height&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;280&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Label&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Content&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;{Binding Path=Name}&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Height&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;25&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Background&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;#96030303&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Grid&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, &quot;Courier New&quot;, courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { 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; }&lt;/style&gt;&lt;br /&gt;&lt;br&gt;I’ve given each of the cover views different background colors to provide visual cues when laying them out. I’ve arranged five of these cover views on my MainWindow inside a parent grid, as shown below&lt;br&gt;&lt;br&gt;&lt;a href=&quot;http://insario.com/media/a1f09b71424d_A4F7/CoverArray.jpg&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;CoverArray&quot; border=&quot;0&quot; alt=&quot;CoverArray&quot; src=&quot;http://insario.com/media/a1f09b71424d_A4F7/CoverArray_thumb.jpg&quot; width=&quot;304&quot; height=&quot;216&quot;&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;Now that the covers are in place, I need a way to provide each of them with an album to bind to. I’ll make these available by creating a viewmodel that the MainWindow can bind to. This MainWindowViewModel will provide an &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms668604.aspx&quot; target=&quot;_blank&quot;&gt;ObservableCollection&lt;/a&gt; of Albums. In the interest of time, I’ll manually populate the ObservableCollection in the viewmodel’s constructor for now, rather than fetching the data from an outside source at runtime. &lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;div class=&quot;csharpcode&quot;&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; MainWindowViewModel : ViewModelBase {&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;  &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; MainWindowViewModel() {&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;      Albums = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; ObservableCollection&amp;lt;Album&amp;gt;();&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;      Albums.Add(&lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Album {&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;          Name = &lt;span class=&quot;str&quot;&gt;&quot;Waking Up&quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;          Artist = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Artist { Name = &lt;span class=&quot;str&quot;&gt;&quot;OneRepublic&quot;&lt;/span&gt; },&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt;          ArtworkUrl = &lt;span class=&quot;str&quot;&gt;&quot;http://image.listen.com/img/170x170/3/3/9/0/1850933_170x170.jpg&quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   8:  &lt;/span&gt;      });&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   9:  &lt;/span&gt;      ....&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;  10:  &lt;/span&gt;  }&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;  11:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;  12:  &lt;/span&gt;  &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; ObservableCollection&amp;lt;Album&amp;gt; Albums { get; set; }&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;  13:  &lt;/span&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, &quot;Courier New&quot;, courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { 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; }&lt;/style&gt;&lt;br /&gt;&lt;br&gt;To make use of the MainWindowViewModel in the parent container, I’ll add a local StaticResource reference to the MainWindowViewModel in the MainWIndow XAML, and bind the DataContext for the parent grid to it.&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;div class=&quot;csharpcode&quot;&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Window&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;x:Class&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;NowPlayingMVVM.MainWindow&quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;        &lt;span class=&quot;attr&quot;&gt;xmlns&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;        &lt;span class=&quot;attr&quot;&gt;xmlns:x&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;        &lt;span class=&quot;attr&quot;&gt;Title&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Zune Wall&quot;&lt;/span&gt; &lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;        &lt;span class=&quot;attr&quot;&gt;xmlns:my&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;clr-namespace:NowPlayingMVVM.View&quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;        &lt;span class=&quot;attr&quot;&gt;xmlns:vm&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;clr-namespace:NowPlayingMVVM.ViewModel&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Width&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;515&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Height&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;325&quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   8:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Window.Resources&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   9:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;vm:MainWindowViewModel&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;x:Key&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;MainVM&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;  10:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Window.Resources&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;  11:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Grid&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Height&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;280&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Width&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;490&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;DataContext&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;{Binding Source={StaticResource MainVM}}&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;  12:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;my:LargeCover&lt;/span&gt;  &lt;span class=&quot;attr&quot;&gt;HorizontalAlignment&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Left&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;VerticalAlignment&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Top&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;  13:  &lt;/span&gt;        ....&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, &quot;Courier New&quot;, courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { 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; }&lt;/style&gt;&lt;br /&gt;&lt;br&gt;By binding the parent grid to an instance of the MainWindowsViewModel, the grid’s child elements can now bind to public properties of the viewmodel. The final step is to bind the DataContext of each cover to one of the Albums in the MainWindowViewModel’s Albums collection.&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;div class=&quot;csharpcode&quot;&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;my:LargeCover&lt;/span&gt;  &lt;span class=&quot;attr&quot;&gt;Margin&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;0,0,0,0&quot;&lt;/span&gt;     &lt;span class=&quot;attr&quot;&gt;DataContext&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;{Binding Path=Albums[0]}&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;my:MediumCover&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Margin&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;280,0,0,0&quot;&lt;/span&gt;   &lt;span class=&quot;attr&quot;&gt;DataContext&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;{Binding Path=Albums[1]}&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;my:SmallCover&lt;/span&gt;  &lt;span class=&quot;attr&quot;&gt;Margin&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;280,210,0,0&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;DataContext&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;{Binding Path=Albums[2]}&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;my:SmallCover&lt;/span&gt;  &lt;span class=&quot;attr&quot;&gt;Margin&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;350,210,0,0&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;DataContext&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;{Binding Path=Albums[3]}&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;my:SmallCover&lt;/span&gt;  &lt;span class=&quot;attr&quot;&gt;Margin&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;420,210,0,0&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;DataContext&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;{Binding Path=Albums[4]}&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, &quot;Courier New&quot;, courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { 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; }&lt;/style&gt;&lt;br /&gt;&lt;br&gt;Yes, this is a quick and dirty approach to the problem, but it validates that our model, views, and viewmodel are working together nicely: &lt;br&gt;&lt;br&gt;&lt;a href=&quot;http://insario.com/media/a1f09b71424d_A4F7/CoverArrayBound.jpg&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;CoverArrayBound&quot; border=&quot;0&quot; alt=&quot;CoverArrayBound&quot; src=&quot;http://insario.com/media/a1f09b71424d_A4F7/CoverArrayBound_thumb.jpg&quot; width=&quot;304&quot; height=&quot;194&quot;&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;h1&gt;What Next?&lt;/h1&gt;&lt;br&gt;I’m still new to MVVM, but even without a lot of experience, this approach doesn’t feel right. A couple of objections right off the top of my head:&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;The data is hard-coded and will need to come from a live source in the future. What will that mean for the UI as data is collected in a background thread? &lt;br /&gt;&lt;li&gt;The views are all bound to a model entity, not a viewmodel. I need to break that connection – MVVM purists say that views shouldn’t know about the underlying model &lt;br /&gt;&lt;li&gt;The album covers are about to a specific index inside the ObservableCollection. I don’t think this will be efficient when I want to update the bound album, as I’ll have to fire a PropertyChanged event on the whole collection if I want my bound element to be notified. But what is the best approach going to be? Should my viewmodel have a property for each album that is bound? That might get out of hand when my view is made up of dozens of album covers. &lt;br /&gt;&lt;li&gt;How will I shuffle the bound collection so that the UI isn’t the same every time? I want to be able to write unit tests when I start working on my shuffle algorithm, which I need to consider as I approach this.&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;a href=&quot;http://insario.com/mvvm/NowPlayingMVVM-Part2.zip&quot; target=&quot;_blank&quot;&gt;Download Project&lt;/a&gt;  </description><link>http://kewleyoncode.blogspot.com/2010/08/now-playing-with-mvvm-part-2.html</link><author>noreply@blogger.com (Josh)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8093175187185319143.post-1241763483953274187</guid><pubDate>Wed, 04 Aug 2010 00:53:00 +0000</pubDate><atom:updated>2010-09-08T17:50:05.884-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">MVVM</category><category domain="http://www.blogger.com/atom/ns#">Zune</category><title>Taking WPF for a ride – Now Playing with MVVM</title><description>This is the first in what I plan to be a multi-part series on my experiences with getting started in WPF development using the MVVM platform. In this series of posts I will aim to reproduce the Now Playing screen of the Zune software, pictured below.&lt;br&gt;&lt;a href=&quot;http://insario.com/media/TakingMVVMforaride_119F2/ZuneNowPlaying.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto&quot; class=&quot;wlDisabledImage&quot; title=&quot;Zune - Now Playing&quot; border=&quot;0&quot; alt=&quot;Zune - Now Playing&quot; src=&quot;http://insario.com/media/TakingMVVMforaride_119F2/ZuneNowPlaying_thumb.jpg&quot; width=&quot;906&quot; height=&quot;477&quot;&gt;&lt;/a&gt;&lt;br&gt;I think the Zune software’s Now Playing screen lends itself well to this type of experiment. It offers a chance to play with:&lt;br&gt; &lt;ul&gt; &lt;li&gt;Complex Layout – figuring out how to organize the album covers should prove to be an interesting challenge.  &lt;li&gt;MVVM and Data binding – what will the best approach be for binding a collection of albums to my interface?  &lt;li&gt;Animations – album cover transitions and the colored overlay  &lt;li&gt;Efficiency concerns – how can I manage all those image assets without consuming an inordinate amount of memory?&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I plan to blog while I develop the application, so I expect my implementation to go through a number of changes. Because of this approach, some of the code I produce along the way will not be best-in-class, and some of the technical approaches will probably change. The idea is to document the journey, not to take a position on what the best approach may be. I’m learning as I go…&lt;br&gt;&lt;br&gt;Ok, enough lead in, let’s get to it.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;Table of contents&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/now-playing-with-mvvm-part-2.html&quot;&gt;Part 2 – M-V-VM Breakdown &amp;amp; Quick implementation&lt;/a&gt;  &lt;li&gt;&lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/now-playing-with-mvvm-part-3.html&quot;&gt;Part 3 - Separating View Models and Services&lt;/a&gt;  &lt;li&gt;&lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/now-playing-with-mvvm-part-4.html&quot;&gt;Part 4 - Replicating the Zune Now Playing layout&lt;/a&gt; &lt;li&gt;&lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/08/fetching-sample-album-artist-song-data.html&quot;&gt;Part 5 – Fetching Sample Album / Artist / Song Data&lt;/a&gt; &lt;li&gt;&lt;a href=&quot;http://kewleyoncode.blogspot.com/2010/09/now-playing-with-mvvm-animating-cover.html&quot;&gt;Part 6 – Animating Cover Transitions&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;  </description><link>http://kewleyoncode.blogspot.com/2010/08/taking-wpf-for-ride-now-playing-with.html</link><author>noreply@blogger.com (Josh)</author><thr:total>0</thr:total></item></channel></rss>