porting a real win8 app to wp8–part 3
It’s been a good while since I last worked on porting Comic Cloud from Windows 8 to Windows Phone. If you can still remember, the goal was to maximize code reuse by using PCL wherever possible.
Part 3 will be the last part in this series, I’m currently holding a fully functional Windows Store app and a Windows Phone 8 app that can navigate pages and sent a search query to the api using a shared service layer. Theoretically everything is shared between the two platforms except the views, which makes sense. But it still required quite a lot of tinkering to get it to work.
PCL is improving
Microsoft is working hard on bringing as many libraries to PCL as they possibly can. In part 2 of the series I already mentioned the portable HttpClient, that library finally gave us a uniform way of doing HTTP requests on multiple platforms. Between part 2 and this part Microsoft has released the PCL version of their Azure Mobile Services SDK (beware! this one has breaking changes if you’re coming over from the platform specific SDK).
Changes in my project
I decided not to use the PCL version of WAMS yet because it has breaking changes and it doesn’t help me get rid of some platform specific projects, so no real use there yet.
What I wanted to achieve for demoing purpose was to get the search functionality working on the phone. The search function on the Windows Store app uses a BlockingCollection (MSDN link) This is a thread safe collection, meaning I can safely prefetch data from one thread while loading data on the other thread. My entire search service is relying on this class (it’s an implementation of the consumer/producer pattern by the way), only problem: Windows Phone doesn’t have the BlockingCollection class. So I could either abstract the search service, change it entirely or implement my own version of the BlockingCollection. The last option seemed like the hardest one to do so I went for it. I’m not entirely sure if I got the exact same functionality of the real BlockingCollection (it does lack some methods and properties, I only implemented what I needed for my app) but here it is
<div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:70f65b5f-f288-44bf-8945-f40e2816b6a8" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">class</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">BlockingCollection</span><span style="background:#ffffff;color:#000000"><T> : </span><span style="background:#ffffff;color:#2b91af">Queue</span><span style="background:#ffffff;color:#000000"><T></span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">readonly</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">object</span><span style="background:#ffffff;color:#000000"> _locker = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">object</span><span style="background:#ffffff;color:#000000">();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">readonly</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Queue</span><span style="background:#ffffff;color:#000000"><T> _itemQ;</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> _canAddItems;</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> BlockingCollection()</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000">_itemQ = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Queue</span><span style="background:#ffffff;color:#000000"><T>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">_canAddItems = </span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">;</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> EnqueueItem(T item)</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">lock</span><span style="background:#ffffff;color:#000000"> (_locker)</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000">_itemQ.Enqueue(item); </span><span style="background:#ffffff;color:#008000">// We must pulse because we're</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">Monitor</span><span style="background:#ffffff;color:#000000">.Pulse(_locker); </span><span style="background:#ffffff;color:#008000">// changing a blocking condition.</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">}</span></li> <li> </li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> TryTake(</span><span style="background:#ffffff;color:#0000ff">out</span><span style="background:#ffffff;color:#000000"> T item, </span><span style="background:#ffffff;color:#0000ff">int</span><span style="background:#ffffff;color:#000000"> millisecondsTimeout, CancellationToken cancellationToken)</span></li> <li> <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">cancellationToken.ThrowIfCancellationRequested();</span></li> <li> </li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000"> (_canAddItems)</span></li> <li> <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">lock</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#0000ff">this</span><span style="background:#ffffff;color:#000000">)</span></li> <li> <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li> <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">item = Dequeue();</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">}</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000">)</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000">item = </span><span style="background:#ffffff;color:#0000ff">default</span><span style="background:#ffffff;color:#000000">(T);</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">false</span><span style="background:#ffffff;color:#000000">;</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">}</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000">item = </span><span style="background:#ffffff;color:#0000ff">default</span><span style="background:#ffffff;color:#000000">(T);</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">false</span><span style="background:#ffffff;color:#000000">;</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> TryAdd(T item, </span><span style="background:#ffffff;color:#0000ff">int</span><span style="background:#ffffff;color:#000000"> millisecondsTimeout, CancellationToken cancellationToken)</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000">cancellationToken.ThrowIfCancellationRequested();</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000"> (_canAddItems)</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">lock</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#0000ff">this</span><span style="background:#ffffff;color:#000000">)</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000">Enqueue(item);</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">;</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000">)</span></li> <li> <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">false</span><span style="background:#ffffff;color:#000000">;</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">}</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">false</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">}</span></li> <li> </li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> CompleteAdding()</span></li> <li> <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">_canAddItems = </span><span style="background:#ffffff;color:#0000ff">false</span><span style="background:#ffffff;color:#000000">;</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div> <p>It’s basically a Queue with some lock statements, it does work for me but I’m not responsible for any accidents that might occur <img class="wlEmoticon wlEmoticon-smile" style="border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none" alt="Glimlach" src="http://www.spikie.be/blog/images/wlEmoticon-smile_19.png" /></p> <h2>Sharing ViewModels</h2> <p>All my viewmodels are in a PCL library, managed to get that to work in part 1. The ViewModelLocator can’t be made portable since some using statements are different and the WP8 version might need some other classes then the win8 version. I decided to add the Windows Store ViewModelLocator as a link into the Windows Phone 8 project, adding in some pre-processor directives made it work like a charm (I make this sound easy but it did take some time to get it just right).</p> <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9edd7779-42ce-405d-a2f6-079e4e0f07a8" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">using</span><span style="background:#ffffff;color:#000000"> ComicDB.Framework;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">using</span><span style="background:#ffffff;color:#000000"> ComicDB.SDKBroker;</span></li> <li><span style="background:#ffffff;color:#0000ff">using</span><span style="background:#ffffff;color:#000000"> ComicDB.View;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">using</span><span style="background:#ffffff;color:#000000"> GalaSoft.MvvmLight;</span></li> <li><span style="background:#ffffff;color:#0000ff">using</span><span style="background:#ffffff;color:#000000"> GalaSoft.MvvmLight.Ioc;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">using</span><span style="background:#ffffff;color:#000000"> Microsoft.Practices.ServiceLocation;</span></li> <li> </li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">#if</span><span style="background:#ffffff;color:#000000"> !WINDOWS_PHONE</span></li> <li><span style="background:#ffffff;color:#808080">using ComicDB.Framework.WinRT;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#808080">using ComicDB.SDKBroker.WinRT;</span></li> <li><span style="background:#ffffff;color:#0000ff">#else</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">using</span><span style="background:#ffffff;color:#000000"> ComicDB.Framework.WP8;</span></li> <li><span style="background:#ffffff;color:#0000ff">using</span><span style="background:#ffffff;color:#000000"> ComicDB.SDKBroker.WP8;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">#endif</span></li> <li> </li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">namespace</span><span style="background:#ffffff;color:#000000"> ComicDB.ViewModel</span></li> <li><span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">class</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">ViewModelLocator</span></li> <li> <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> ViewModelLocator()</span></li> <li> <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">ServiceLocator</span><span style="background:#ffffff;color:#000000">.SetLocatorProvider(() => </span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default);</span></li> <li> </li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">ViewModelBase</span><span style="background:#ffffff;color:#000000">.IsInDesignModeStatic)</span></li> <li> <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">// Create design time view services and models</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//SimpleIoc.Default.Register<IDataService, DesignDataService>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">}</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">else</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">// Create run time view services and models</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">#if</span><span style="background:#ffffff;color:#000000"> !WINDOWS_PHONE</span></li> <li> <span style="background:#ffffff;color:#808080">SimpleIoc.Default.Register<ComicDB.Framework.Interface.INavigationService, ComicDB.Framework.WinRT.NavigationService>();</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">#else</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<ComicDB.Framework.Interface.</span><span style="background:#ffffff;color:#2b91af">INavigationService</span><span style="background:#ffffff;color:#000000">, ComicDB.Framework.WP8.</span><span style="background:#ffffff;color:#2b91af">NavigationService</span><span style="background:#ffffff;color:#000000">>();</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">#endif</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">IService</span><span style="background:#ffffff;color:#000000">, </span><span style="background:#ffffff;color:#2b91af">Service</span><span style="background:#ffffff;color:#000000">>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">IMessageApi</span><span style="background:#ffffff;color:#000000">, </span><span style="background:#ffffff;color:#2b91af">MessageApi</span><span style="background:#ffffff;color:#000000">>();</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">IFrameworkApi</span><span style="background:#ffffff;color:#000000">, </span><span style="background:#ffffff;color:#2b91af">FrameworkApi</span><span style="background:#ffffff;color:#000000">>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">IDispatcher</span><span style="background:#ffffff;color:#000000">, </span><span style="background:#ffffff;color:#2b91af">Dispatcher</span><span style="background:#ffffff;color:#000000">>();</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">INetworkApi</span><span style="background:#ffffff;color:#000000">, </span><span style="background:#ffffff;color:#2b91af">NetworkApi</span><span style="background:#ffffff;color:#000000">>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">}</span></li> <li> </li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//register views</span></li> <li><span style="background:#ffffff;color:#0000ff">#if</span><span style="background:#ffffff;color:#000000"> !WINDOWS_PHONE</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#808080">SimpleIoc.Default.Register<IMainPage, MainPage>();</span></li> <li> <span style="background:#ffffff;color:#808080">SimpleIoc.Default.Register<IVolumeDetailPage, VolumeDetailPage>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#808080">SimpleIoc.Default.Register<ICharacterDetailPage, CharacterDetailPage>();</span></li> <li> <span style="background:#ffffff;color:#808080">SimpleIoc.Default.Register<ICollectionPage, CollectionPage>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#808080">SimpleIoc.Default.Register<IDetailPage, DetailPage>();</span></li> <li> <span style="background:#ffffff;color:#808080">SimpleIoc.Default.Register<IIssueDetailPage, IssueDetailPage>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#808080">SimpleIoc.Default.Register<ILocationDetailPage, LocationDetailPage>();</span></li> <li> <span style="background:#ffffff;color:#808080">SimpleIoc.Default.Register<INewsFeedPage, NewsFeedPage>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#808080">SimpleIoc.Default.Register<IPersonDetailPage, PersonDetailPage>();</span></li> <li> <span style="background:#ffffff;color:#808080">SimpleIoc.Default.Register<IStoryArcDetailPage, StoryArcDetailPage>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#808080">SimpleIoc.Default.Register<ITeamDetailPage, TeamDetailPage>();</span></li> <li><span style="background:#ffffff;color:#0000ff">#endif</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//register viewmodels</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">MainViewModel</span><span style="background:#ffffff;color:#000000">>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">VolumeDetailViewModel</span><span style="background:#ffffff;color:#000000">>(</span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">);</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">CharacterDetailViewModel</span><span style="background:#ffffff;color:#000000">>(</span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">);</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">TeamDetailViewModel</span><span style="background:#ffffff;color:#000000">>(</span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">);</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">IssueDetailViewModel</span><span style="background:#ffffff;color:#000000">>(</span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">);</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">SearchViewModel</span><span style="background:#ffffff;color:#000000">>();</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">DetailViewModel</span><span style="background:#ffffff;color:#000000">>(</span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">);</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">StoryArcDetailViewModel</span><span style="background:#ffffff;color:#000000">>(</span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">);</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">LocationDetailViewModel</span><span style="background:#ffffff;color:#000000">>(</span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">);</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">PersonDetailViewModel</span><span style="background:#ffffff;color:#000000">>(</span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">);</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">CollectionViewModel</span><span style="background:#ffffff;color:#000000">>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">SimpleIoc</span><span style="background:#ffffff;color:#000000">.Default.Register<</span><span style="background:#ffffff;color:#2b91af">NewsFeedViewModel</span><span style="background:#ffffff;color:#000000">>(</span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">);</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">MainViewModel</span><span style="background:#ffffff;color:#000000"> Main</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">get</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">ServiceLocator</span><span style="background:#ffffff;color:#000000">.Current.GetInstance<</span><span style="background:#ffffff;color:#2b91af">MainViewModel</span><span style="background:#ffffff;color:#000000">>();</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">}</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//... all other VM properties follow here, left out for demo purpose</span></li> </ol> </div> </div> </div> <p>The pre-processor directives make the class look a bit dirty but it does get the job done.</p> <p>At this point the WP8 app started and showed me the mainpage, with the mainviewmodel being its datacontext. Now I wanted to add an appbar with a searchbutton, a few problems there:</p> <ul> <li>the default appbar is not bindable (solved with Cimbalino) </li> <li>the mainviewmodel doesn’t have a command to navigate to the searchpage since Windows Store uses the Search charm </li> </ul> <p>I decided to take the quick and dirty solution here so I added a normal appbar with a button and a navigation statement in code behind. The SearchPage has SearchViewModel as datacontext. In Windows Store it was normal for the SearchText property to be immediately holding a value since it came from the Search charm, not the case in WP8. Small change to the viewmodel so that it doesn’t fire its Search function when SearchText is empty or null. This was the result after all my hard work</p> <p><a href="http://i37.tinypic.com/igwzlh.jpg" target="_blank"><img src="http://i37.tinypic.com/igwzlh.jpg" width="518" height="303" /></a> </p> <p>Mission accomplished!</p> <h2>Conclusion</h2> <p>PCL still has a long way to go but it is improving, and for some cases it can actually already be very useful (for example to share model classes over different platforms).</p> <p>I would however advice against going for maximum code reuse, it all sounds great but the reality is very different. I had to make a lot of decisions, change quite a lot of architecture and even add missing classes (like the BlockingCollection).</p> <p>My advice if you want to build a multiplatform app: use PCL to share your model, maybe even some small framework with helper classes, but build a custom implementation of service layers and viewmodels for each platform, it will save you a lot of hassle and probably even time. If you do decide to go for maximum code reuse, make sure that you really really think about it when you design your architecture, make sure that every little thing has an abstraction better one interface too many than having to rewrite a class.</p> <p>Here’s a comparing screenshot between the solution before and after adding the WP8 project and refactoring everything.</p> <p><a href="http://i37.tinypic.com/n1uphu.jpg" target="_blank"><img src="http://i37.tinypic.com/n1uphu.jpg" width="360" height="189" /></a></p> <p><script type="text/javascript"><!-- google_ad_client = "ca-pub-2343948435149147"; /* spikie.be underpost */ google_ad_slot = "9230774310"; google_ad_width = 468; google_ad_height = 60; //--> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script></p>
This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.
Leave a Comment