<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-31900010</id><updated>2011-12-10T11:15:04.207Z</updated><category term='C#'/><category term='LINQ'/><category term='SAP'/><category term='Custom Control'/><category term='Xaml'/><category term='MVVM'/><category term='Metro'/><category term='Technology'/><category term='Prism'/><category term='Win 8'/><category term='Extension Methods'/><category term='Modularity'/><category term='.Net'/><category term='CodeProject'/><category term='Design Patterns'/><category term='WPF'/><category term='UI Design'/><title type='text'>Ron Gramann</title><subtitle type='html'>.Net Software Development</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>32</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-31900010.post-2821994184341816339</id><published>2011-09-19T21:38:00.000+01:00</published><updated>2011-09-19T21:38:02.046+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Win 8'/><category scheme='http://www.blogger.com/atom/ns#' term='Metro'/><title type='text'>Windows 8: First Impressions</title><content type='html'>The wait is over, and by now many of you have had a chance to take Windows 8 Developer Preview for a test drive. &amp;nbsp;I haven't spent a huge amount of time with Win 8, but enough to form some initial opinions.&lt;br /&gt;&lt;b&gt;&lt;br /&gt;Start Screen and Touch&lt;/b&gt;&lt;br /&gt;It appears Microsoft has opted to bring Touch front and center, as evidenced by the Start screen. &amp;nbsp;Unfortunately the experience is not terribly rewarding for desktop users with a traditional keyboard and mouse. &amp;nbsp;I am being kind here. &amp;nbsp;In fact, after spending a couple of hours with the Start screen I was looking for ways to turn it off. &amp;nbsp;Not because it is bad, just unnecessary. &amp;nbsp; I would liken it to running Media Center has your main shell. &amp;nbsp;Nice to look at, but in terms of productivity and value add, it brings very little to the table. &amp;nbsp;Great for tablets, but please Microsoft, make it optional for desktop users.&lt;br /&gt;Desktop users are desktop users because we use a keyboard and mouse out of necessity; because we are primarily using applications like Visual Studio, Photoshop and Office. &amp;nbsp;I have no intention of running these applications on a tablet. So why impose obvious tablet-design on users who don't need them?&lt;br /&gt;&lt;b&gt;&lt;br /&gt;Metro UI&lt;/b&gt;&lt;br /&gt;I am a big fan of Metro UI design and Win 8 has it in spades. &amp;nbsp;But again, this is central to the new shell and is of value to tablet users. &amp;nbsp;It feels like the desktop has taken a backseat, with Metro hogging the limelight. &amp;nbsp;On the desktop we see very little Metro influence, which is unfortunate, because Metro design principles could be put to good use. &amp;nbsp;For example, take a look at the newly designed Task Manager.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-MQtMYg5tBD8/TneiWyJa4sI/AAAAAAAAABY/zO2XpwkcjyE/s1600/Win8TaskManager.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="258" src="http://2.bp.blogspot.com/-MQtMYg5tBD8/TneiWyJa4sI/AAAAAAAAABY/zO2XpwkcjyE/s320/Win8TaskManager.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;This design is influenced by Metro and is beautiful. &amp;nbsp;I would like to see the entire desktop adopt a similar look and feel. &lt;br /&gt;Windows has been&amp;nbsp;criticized for being Windows. &amp;nbsp;That rectangular boxes with content that can be minimized and resized were so 90s. &amp;nbsp;So what? &amp;nbsp;It's actually pretty workable, which is maybe why it's been with us for so long. &amp;nbsp;Could it use a facelift? Sure, but I don't see the value in discarding it as a concept. &amp;nbsp;But, with the time I've spent with Win 8 it feels like Microsoft is almost ashamed of its roots. &amp;nbsp;And that Metro represents it's commitment to it's new forward-thinking Un-Window philosophic shift. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Eco-System&lt;/b&gt;&lt;br /&gt;Microsoft's goal of a computing eco-system has been getting a lot of press. &amp;nbsp;I just have to ask Why? &amp;nbsp;Why an eco-system? &amp;nbsp;Why does my phone, tablet, laptop, desktop and TV have to share the same user experience? &amp;nbsp;Are the IT consumers so thick that they just can't cope with differences across these devices? &amp;nbsp;I think not. &amp;nbsp;If Windows 8 is the solution, what is the problem? &amp;nbsp;I've never felt stressed out that I use Android on my phone, Win 7 on the laptop/desktop, Media Center on the TV, and more recently WebOS on the tablet. &amp;nbsp;There are things I like and dislike about each of those. &amp;nbsp;I've never sat there and dreamt of a perfect world where all these devices work and function the same way...ahhh...think of it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;I understand it is early days, but my initial impressions of Win 8 were disappointing. &amp;nbsp;It feels too devoted to touch and IT consumers and less to hardcore computing (software development, databases, CGI, etc). &amp;nbsp;In its current state, I'll be looking for the "run as Win 7" hack.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-2821994184341816339?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/2821994184341816339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=2821994184341816339' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2821994184341816339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2821994184341816339'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2011/09/windows-8-first-impressions.html' title='Windows 8: First Impressions'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-MQtMYg5tBD8/TneiWyJa4sI/AAAAAAAAABY/zO2XpwkcjyE/s72-c/Win8TaskManager.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-7037694386174121826</id><published>2011-07-25T21:12:00.000+01:00</published><updated>2011-07-25T21:12:31.848+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Metro'/><category scheme='http://www.blogger.com/atom/ns#' term='UI Design'/><title type='text'>Metro for Dummies Part 4</title><content type='html'>I've adjusted my font sizes, along with my target screen size (1280 x 720).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-qw7HiXKv5tY/Ti3AW-uIt_I/AAAAAAAAABI/uUk-r-hdxT0/s1600/metroMain.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://2.bp.blogspot.com/-qw7HiXKv5tY/Ti3AW-uIt_I/AAAAAAAAABI/uUk-r-hdxT0/s320/metroMain.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I'm now going to turn my attention to my colour palette.&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Picking your Palette&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Because your Metro design is minimalistic, selecting the right font and palette is crucial for the whole design to work.&lt;br /&gt;&lt;br /&gt;There are plenty of resources on the web which details the science of colour and colour combinations. &amp;nbsp;I tend to pick my palette based on what looks good or what works. &amp;nbsp;I know this is not terribly precise, and there probably is a methodology to do this.&lt;br /&gt;&lt;br /&gt;I like to work with tools like &lt;a href="http://kuler.adobe.com/"&gt;Kuler&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I don't think there is any right or wrong here. &amp;nbsp;Similiar to picking your font, you need to play with it until it seems right.&lt;br /&gt;&lt;br /&gt;For my sample application I've chosen this palette for my black background.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-gtliC-Apt3U/Ti3GYYpILYI/AAAAAAAAABM/_3M6w8NFbzI/s1600/palette.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-gtliC-Apt3U/Ti3GYYpILYI/AAAAAAAAABM/_3M6w8NFbzI/s1600/palette.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Applying my colour palette to my mock-ups...&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-wLZlLyHkR_0/Ti3LWmGt_GI/AAAAAAAAABQ/Jj0PJntO83g/s1600/metroMenuColour.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-wLZlLyHkR_0/Ti3LWmGt_GI/AAAAAAAAABQ/Jj0PJntO83g/s1600/metroMenuColour.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-jSZ6ytAzPLE/Ti3Lmu6jzgI/AAAAAAAAABU/RdvFtd_p57M/s1600/metroSearchColour.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="263" src="http://4.bp.blogspot.com/-jSZ6ytAzPLE/Ti3Lmu6jzgI/AAAAAAAAABU/RdvFtd_p57M/s320/metroSearchColour.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Next, I will need to nail down colour conventions for various controls and states (Hover, Disabled, Invalid, Selected, etc). &amp;nbsp;This may require expanding my palette, but should not require additional core colours.&lt;/div&gt;&lt;br /&gt;Until I am satisfied with a full application screen mock-up, maybe a search screen with search results and a detail dialog, the colour assignments are likely to get shifted around. &amp;nbsp;I think consistency is probably more important than precision when working this out. &amp;nbsp;I'm sure you could find an expert to tell you this colour should or shouldn't be used with that colour. &amp;nbsp;But, at the end of the day, it's about what your client likes and fulfilling the purpose of the application. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-7037694386174121826?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/7037694386174121826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=7037694386174121826' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/7037694386174121826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/7037694386174121826'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2011/07/metro-for-dummies-part-4.html' title='Metro for Dummies Part 4'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-qw7HiXKv5tY/Ti3AW-uIt_I/AAAAAAAAABI/uUk-r-hdxT0/s72-c/metroMain.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-323019836476361903</id><published>2011-07-24T20:35:00.001+01:00</published><updated>2011-07-24T20:36:46.219+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Metro'/><category scheme='http://www.blogger.com/atom/ns#' term='UI Design'/><title type='text'>Metro for Dummies Part 3</title><content type='html'>&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Font Sizes&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Once I've selected my base font I then work out font sizes. &amp;nbsp;This is best done in Photoshop or other graphics application. &amp;nbsp;I prefer to use a Word/HTML/CSS styled naming convention for my font size (H1, H2, H3, etc).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://4.bp.blogspot.com/-rkGF8SnFIBs/TixvhH5CZwI/AAAAAAAAAA8/K8ufCJBFm2Q/s1600/MetroFontSizes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="105" src="http://4.bp.blogspot.com/-rkGF8SnFIBs/TixvhH5CZwI/AAAAAAAAAA8/K8ufCJBFm2Q/s400/MetroFontSizes.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;This is often influenced by the target device. &amp;nbsp;In the example above, I'm targeting a laptop/desktop device with a minimum screen resolution of 1024 by 768.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I'll then mock-up some sample uses of these fonts and sizes, still working in Photoshop. &amp;nbsp;This gives me a feel for the sizes, screen real estate and spacings. &amp;nbsp;I'm not sure what you would call this? Feng shui, for a lack of better term. &amp;nbsp;But there seems to be a natural balance of content, space and function.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://2.bp.blogspot.com/-OUh4hf-ackM/Tixxu6v5UEI/AAAAAAAAABA/Ht1do2gHdYg/s1600/searchMain.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-OUh4hf-ackM/Tixxu6v5UEI/AAAAAAAAABA/Ht1do2gHdYg/s320/searchMain.png" width="316" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-rFAkVceTFmw/Tixx8YhAm1I/AAAAAAAAABE/8ri85599NUQ/s1600/searchAgent.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="283" src="http://4.bp.blogspot.com/-rFAkVceTFmw/Tixx8YhAm1I/AAAAAAAAABE/8ri85599NUQ/s320/searchAgent.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I usually do this without using a colour palette. &amp;nbsp;I don't want the colours to bias my perception of the content and space. &amp;nbsp;Once I apply my palette, it should enhance my design. &amp;nbsp;But my design should not depend on the palette. &amp;nbsp;So, I make it work without one.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Do as many mock-ups as needed. &amp;nbsp;Time spent in Photoshop is well spent. &amp;nbsp;I find that the simplicity of Metro makes this process quick and painless. &amp;nbsp;What you're really doing is establishing UI conventions for your application.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-323019836476361903?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/323019836476361903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=323019836476361903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/323019836476361903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/323019836476361903'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2011/07/metro-for-dummies-part-3.html' title='Metro for Dummies Part 3'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-rkGF8SnFIBs/TixvhH5CZwI/AAAAAAAAAA8/K8ufCJBFm2Q/s72-c/MetroFontSizes.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-6222259859432633855</id><published>2011-07-24T16:32:00.001+01:00</published><updated>2011-07-24T16:33:50.534+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Metro'/><category scheme='http://www.blogger.com/atom/ns#' term='UI Design'/><title type='text'>Metro for Dummies Part 2</title><content type='html'>&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Font Samples&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The following is a collection of fonts which are primarily used for public signage. &amp;nbsp;Not all of these would be suitable for a Metro-styled user interface, but will give you some ideas on selecting a base font for your design.&lt;br /&gt;&lt;br /&gt;Austria&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/7/74/Hinweiszeichen_15a-d.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/7/74/Hinweiszeichen_15a-d.svg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Brusseline&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/7/70/Brusseline_name.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="60" src="http://upload.wikimedia.org/wikipedia/commons/7/70/Brusseline_name.svg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Calvert&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/en/6/6d/Metro-Wiki-logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://upload.wikimedia.org/wikipedia/en/6/6d/Metro-Wiki-logo.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Casey&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/c/c1/Casey_Showcase.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/c/c1/Casey_Showcase.png" width="271" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Clearview&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/9/94/Clearview_sample.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="116" src="http://upload.wikimedia.org/wikipedia/commons/9/94/Clearview_sample.svg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;DIN 1451&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/0/09/DIN_1451.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/0/09/DIN_1451.svg" width="270" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Drogowskaz&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/6/64/Drogowskaz_sample.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/6/64/Drogowskaz_sample.svg" width="272" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;FF Meta&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/1/1b/FFMeta.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/1/1b/FFMeta.svg" width="270" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Frutiger&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/a/ab/FrutigerSpec.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://upload.wikimedia.org/wikipedia/commons/a/ab/FrutigerSpec.svg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;FHWA Series fonts&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/6/6b/Highway_Gothic_sample.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="123" src="http://upload.wikimedia.org/wikipedia/commons/6/6b/Highway_Gothic_sample.svg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;Futura&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/5/50/Futura_Specimen.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://upload.wikimedia.org/wikipedia/commons/5/50/Futura_Specimen.svg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Gill Sans&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/4/48/GillSansEG.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/4/48/GillSansEG.svg" width="270" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Helvetica&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/2/28/HelveticaSpecimenCH.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/2/28/HelveticaSpecimenCH.svg" width="270" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Helvetica Neue&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/0/00/Helvetica_Neue_typeface_weights.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="232" src="http://upload.wikimedia.org/wikipedia/commons/0/00/Helvetica_Neue_typeface_weights.svg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Johnston&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/9/99/Piccadilly_T5_Extension.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="239" src="http://upload.wikimedia.org/wikipedia/commons/9/99/Piccadilly_T5_Extension.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Motorway&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/d/d8/Motorway-font-UK.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://upload.wikimedia.org/wikipedia/commons/d/d8/Motorway-font-UK.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Myriad&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/4/48/Myriadsp.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://upload.wikimedia.org/wikipedia/commons/4/48/Myriadsp.svg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;NPS Rawlinson Roadway&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/1/1c/Font_rawlinson.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="130" src="http://upload.wikimedia.org/wikipedia/commons/1/1c/Font_rawlinson.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Parisine&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/4/48/Station_Monceau_Ligne_2_-_Plaque_02-03-06.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="256" src="http://upload.wikimedia.org/wikipedia/commons/4/48/Station_Monceau_Ligne_2_-_Plaque_02-03-06.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Rail Alphabet&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/4/46/Railalphabet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/4/46/Railalphabet.png" width="270" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Rotis Serif&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/6/6b/Rotisng.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/6/6b/Rotisng.svg" width="270" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;Toronto Subway Font&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/5/51/Queens_Park_Station_curved_tile.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://upload.wikimedia.org/wikipedia/commons/5/51/Queens_Park_Station_curved_tile.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Transport&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f9/Road.sign.arp.750pix.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="266" src="http://upload.wikimedia.org/wikipedia/commons/f/f9/Road.sign.arp.750pix.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Tratex&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/b/b7/Tratex_font_sample.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/b/b7/Tratex_font_sample.png" width="260" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Univers&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/d/d3/Univers_Specimen.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://upload.wikimedia.org/wikipedia/commons/d/d3/Univers_Specimen.svg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-6222259859432633855?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/6222259859432633855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=6222259859432633855' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/6222259859432633855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/6222259859432633855'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2011/07/metro-for-dummies-part-2.html' title='Metro for Dummies Part 2'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-8647881015719095389</id><published>2011-07-24T14:51:00.004+01:00</published><updated>2011-07-24T14:56:59.074+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Metro'/><category scheme='http://www.blogger.com/atom/ns#' term='UI Design'/><title type='text'>Metro for Dummies Part 1</title><content type='html'>I have been experimenting with Microsoft’s Metro Design Language for the past couple of months, and wanted to share some ideas and tips I’ve picked up along the way. &amp;nbsp;I do not claim to be an expert on the subject, nor do I consider myself to be a visual designer. &amp;nbsp;I know what I like, but not always able to tell you why.&lt;br /&gt;&lt;br /&gt;For those unfamiliar with Metro here is a good place to start:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/design/toolbox/tutorials/windows-phone-7/metro/"&gt;Metro Design Language of Windows Phone 7&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I do &lt;b&gt;not&lt;/b&gt; recommend &lt;a href="http://www.amazon.co.uk/Metro-Design-Language-Frederic-Miller/dp/6134242403/ref=sr_1_1?ie=UTF8&amp;amp;qid=1311285205&amp;amp;sr=8-1"&gt;Metro Design Language&lt;/a&gt; being sold by Amazon. &amp;nbsp;It is a self-published book which contains about three pages on Metro UI and the rest is a copy and paste from Microsoft’s back catalogue. &amp;nbsp;At £29.00 it is quite simply, a rip-off.&lt;br /&gt;&lt;br /&gt;Most references on the web speak of Metro and Windows Phone 7 in the same breath. &amp;nbsp;While it is true WP7 does incorporate the Metro design philosophy, it is however not alone; Zune, Xbox 360 and Windows Media Center utilise Metro to a greater or lesser degree.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;What is Metro?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Metro is an internal code name for a typography-based design language created by Microsoft.&lt;br /&gt;&lt;br /&gt;Microsoft defines Metro as..&lt;br /&gt;&lt;b&gt;Typography&lt;/b&gt;. Type is beautiful. Not only is it attractive to the eye, but it can also be functional. The right balance of weight and positioning can create a visual hierarchy. Additionally, well placed type can help lead you to more content.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Motion&lt;/b&gt; is what brings the interface to life. Transitions are just as important as graphical design. By developing a consistent set of motions or animations, a system is created that provides context for usability, extra dimension and depth and improves the perceived performance of the whole interface.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Content not Chrome&lt;/b&gt; is one of the more unique principles of Metro. By removing all notions of extra chrome in the UI, the content becomes the main focus. This is especially relevant due to the smaller screen size and gesture-based interactions.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Honesty&lt;/b&gt;. Design explicitly for the form factor of a hand held device using touch, a high resolution screen and simplified and expedited forms of interaction. In other words, be “authentically digital”&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Gone are the days of Microsoft's User Interface Guidelines for Windows with its precision pixel specifications. &amp;nbsp;Metro represents a dramatic shift away from UI design. &amp;nbsp;Metro is much more fluid and dynamic.&lt;/div&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Picking a base font&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Since typography is central to a Metro design it's good to start with a nice clean font. &amp;nbsp;Your target device may influence what type of font you use. &amp;nbsp;My personal favourites, which look great on mobile devices as well as the desktop are:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Seqoe WP&lt;/b&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f7/Segoe_UI_sample.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="122" src="http://upload.wikimedia.org/wikipedia/commons/f/f7/Segoe_UI_sample.svg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Avenir&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/0/07/AvenirSP.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/0/07/AvenirSP.png" width="270" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Segoe WP is a member of the Segoe font family specifically designed for WP7&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Since Metro borrows heavily from civic and urban design, it is not surprising to find this last font used by the City of Amsterdam, as well as the Dallas airport and Hong Kong airport.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;In many ways the design goals of public signage and Metro are alike. &amp;nbsp;They both seek to provide instant communication in a clean, unadulterated way. &amp;nbsp;The “user” has but seconds to understand and duplicate some piece of information while travelling down the motorway or while on a high-speed train. &amp;nbsp;Likewise, we want to provide instant understanding for our mobile user, often at a glance.&lt;/div&gt;&lt;div&gt;I have to admit this whole area of typography is somewhat addictive. &amp;nbsp;If you can recognise the aesthetics of the font, searching and viewing fonts can be time consuming; there are so many fantastic fonts to choose from. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;div&gt;If you’re interested, this is a good jumping off point:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://en.wikipedia.org/wiki/Public_signage_typefaces"&gt;Signage Typeface&lt;/a&gt; at Wikipedia&lt;/div&gt;&lt;div&gt;You have been warned.&lt;/div&gt;&lt;div&gt;&lt;div&gt;It is worth spending some time selecting your font. &amp;nbsp;It is going to dominate your Metro design.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-8647881015719095389?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/8647881015719095389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=8647881015719095389' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/8647881015719095389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/8647881015719095389'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2011/07/metro-for-dummies-part-1.html' title='Metro for Dummies Part 1'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-698968211494789444</id><published>2011-04-07T07:22:00.004+01:00</published><updated>2011-04-07T07:29:32.862+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Prism'/><category scheme='http://www.blogger.com/atom/ns#' term='Modularity'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>MVVM Revisited</title><content type='html'>I have been working with MVVM and Prism for a couple of years now and have had some recent revelations which you may find useful. &amp;nbsp;Working with MVVM by itself, is relatively straightforward. &amp;nbsp; Combine it with other patterns, such as MVC and IoC, and things can get complicated.&lt;br /&gt;&lt;br /&gt;Here is a common implementation of MVVM:&lt;br /&gt;&lt;div&gt;&lt;a href="http://www.gramann.co.uk/images/old-mvvm.png"&gt;&lt;br /&gt;&lt;img src="http://www.gramann.co.uk/images/old-mvvm.png" width="400" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;This example also utilises a CustomerController along with some services, all of which are supplied by the “Model”. &amp;nbsp;If you’ve worked with Prism you’ll probably recognise this rather unorthodox implementation of MVC, something I’ve never been comfortable with. &amp;nbsp;Injecting a controller into a ViewModel seems backasswards to me. &amp;nbsp;I would prefer to have the Controller be aware of the ViewModel and indirectly control/manage the Views.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Aside from being awkward, this approach does work. &amp;nbsp;But don’t expect your modules to be “modular”. &amp;nbsp;Sure, within your solution it will have the appearance of being a module, but it won’t very portable. &amp;nbsp;If you’re persistent and are dedicated, you can try to “reuse” the Customer module above, but be prepared to drag a half dozen dependent assemblies with it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, what is modularity without portability? &amp;nbsp;Without portability, modularity is reduced to a code organisation concept. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Looking over this situation it occurred to me that the injection of dependencies in the ViewModel was pretty much unrestrained. &amp;nbsp;If the ViewModel needed it, just add another parameter to the constructor. &amp;nbsp;The entire Model was wide-open for consumption, provided it was registered with Unity. &amp;nbsp;Needless to say, this leads to greater and greater consumption, until finally the ViewModel is entrenched in implementation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When viewed as a microcosm, MVVM can act like a tiered architecture. &amp;nbsp;And tiered architectures are great for scalable server applications, but pretty much ruin any hopes of portability. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The other undesirable aspect of this is, while the ViewModel may require the ability to display a MessageBox (provided by the IMessageService), it has no use for the other 10+ methods provided by the service. &amp;nbsp;So, why not give it exactly what it needs – and no more.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One way to accomplish this through the introduction of a custom Model class:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.gramann.co.uk/images/new-mvvm.png"&gt;&lt;br /&gt;&lt;img src="http://www.gramann.co.uk/images/new-mvvm.png" width="400" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Here the CustomerModel class defines exactly what the ViewModel demands of the Model. &amp;nbsp;In effect, it is a subset of the Model and is specific to that ViewModel. &amp;nbsp; It’s the ViewModel’s shopping list – “if you’re going to use me, this is my list of demands”. &amp;nbsp;It is now up to the implementer to provide this functionality – which is where the responsibility belongs.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With this approach the ViewModel has now been liberated and all of the “dependencies” removed. &amp;nbsp;Service methods have been replaced with delegates. &amp;nbsp;The ICustomerService can reside in the module itself, effectively making the CustomerModule a self-contained, standalone assembly.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A side benefit is that the View now contains no code-behind and is no longer dependent on the ViewModel interface.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While working through this I’ve created a new Prism sample solution, which includes a CustomerModule and an OrdersModule, Implementation project and a Shell. &amp;nbsp;I have reduced the module dependency down to a single Core assembly. &amp;nbsp;The Implementation project contains controllers, core services, a persistence manager, etc. &amp;nbsp;It knows about the modules and can orchestrate the workflow and manage the views. &amp;nbsp;The controllers “wire up” the Model and inject them into the ViewModels. &amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At the moment, CustomerModule + Core is about as portable as it gets.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-698968211494789444?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/698968211494789444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=698968211494789444' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/698968211494789444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/698968211494789444'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2011/04/mvvm-revisited.html' title='MVVM Revisited'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-3387077590100076969</id><published>2010-10-17T13:18:00.010+01:00</published><updated>2010-10-17T13:31:34.611+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>When isCode != Code?</title><content type='html'>You could say there are as many different coding styles as there are coders. &amp;nbsp;One in particular I find perplexing is the "inverse logic" approach. &amp;nbsp;I knew a developer to seemed to think 180 degrees from everyone else on the team. &amp;nbsp;Allow me to explain...&lt;br /&gt;&lt;br /&gt;If we were designing a custom control, you may expect to find an &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;IsVisible &lt;/span&gt;property. &amp;nbsp;This "inverse coder" would prefer an &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;IsHidden &lt;/span&gt;property. &amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;IsEnabled &lt;/span&gt;becomes &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;IsDisabled&lt;/span&gt;, etc.&lt;br /&gt;&lt;br /&gt;Within a method you may see something like:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;public void SomeMethod()&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; if(isSomeFlag)&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//do something meaningful...&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Our "inverse coder" would see it like:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;public void SomeMethod()&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; if(!isSomeFlag)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; //do something meaningful...&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;My personal preference is to limit the number of exit points in a method, as in the former. &amp;nbsp;In complex methods, this individual would have several exit points all based upon some inverted logic. &amp;nbsp;Did it work? &amp;nbsp;Technically yes. &amp;nbsp;Was it intuitive and easy to follow? &amp;nbsp;Most times not. &amp;nbsp;The rest of the team, knowingly or unknowningly had to continually shift mental gears when debugging this code. &amp;nbsp;Based on this fact alone, I would say this is bad code, since it was inherently difficult to understand. &amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;Another example...let's say you want to write a method which processes an order, something like:&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;public void ProcessOrder(IOrder order)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; if(order.Status == OrderStatus.Open)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//order processing logic here...&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Pretty straightforward. &amp;nbsp;Our inverted coder sees it completely different, and goes has far to pervert the name of the method itself.&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;public void ProcessNonOpenOrder(IOrder order)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; if(order.Status == OrderStatus.Open)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Difficult where to begin to say what is wrong with that, other than it is more complicated than it needs to be. &amp;nbsp;As a coder I would expect to find an additional &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;ProcessOpenOrder&amp;nbsp;&lt;/span&gt;method to compliment this one, unfortunately not.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;Another common inverse is:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;if(null == someInstance)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;as oppose to the more generally agreed upon:&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;if(someInstance == null)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;or, my personal pet peeve:&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;if(0 &amp;gt;= myCollection.Count)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;I simply have a bone-deep rejection of this. &amp;nbsp;And whenever I encounter it I have to stop and think about what it means. &amp;nbsp;Perhaps this is due to my own training patterns, years and years of well established coding practices, commonly agreed upon by most coders. &amp;nbsp;And I have to ask "What is the advantage of this? &amp;nbsp;What does it buy me to do it this way?" &amp;nbsp;I've searched and cannot find a reason.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;I always strive to make my code simple, obvious and self-documenting. &amp;nbsp;Cryptic code is bad code, complex code is bad code. &amp;nbsp;When writing code as part of a team, self-expression or personal preferences have nothing to do with it. &amp;nbsp;What is important is that it is in alignment with the standards and practices of the rest of the team. &lt;br /&gt;&lt;br /&gt;Including the way they "think".&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-3387077590100076969?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/3387077590100076969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=3387077590100076969' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/3387077590100076969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/3387077590100076969'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2010/10/when-iscode-code.html' title='When isCode != Code?'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-1474390500278930284</id><published>2010-09-20T11:01:00.001+01:00</published><updated>2010-09-20T11:03:19.419+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SAP'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Update</title><content type='html'>After months of defect resolution and testing our code finally shipped this morning. &amp;nbsp;The effort to deliver this product was beyond anyone's&amp;nbsp;estimation. &amp;nbsp;The difficulty was not so much on the .Net front, but more in the area of system coordination.&lt;br /&gt;&lt;br /&gt;Some background...we set out to develop a WPF/Prism application which would be run on a mobile handheld device (think fat, rugged iPad). &amp;nbsp;That, in itself, is not terribly difficult, it was everything else that proved to be challenging. &amp;nbsp;Namely four separate SAP systems, all contributing data which get bundled up and distributed to the mobile device via SAP's NetWeaver. &amp;nbsp;And then back up again...&lt;br /&gt;&lt;br /&gt;On a good day it's hard enough to get SAP to play with SAP, raise that to the fourth power and add SAP's own client&amp;nbsp;synchronization framework in the mix...well, you get the idea. &amp;nbsp;It's a minor miracle it works at all.&lt;br /&gt;&lt;br /&gt;This is my second large SAP/.Net development project, and this one being the largest and most complex of the two. &amp;nbsp;Now, I'm the first to admit that I can be a techno-bigot. &amp;nbsp;I love working with C# and .Net and frameworks like Prism and MEF. &amp;nbsp;There is a real elegance that can be achieved and when you get it right it's poetry in motion. &lt;br /&gt;&lt;br /&gt;Compare that with SAP...well, it's a dinosaur. &amp;nbsp;A plodding,&amp;nbsp;kludgey&amp;nbsp;artifact&amp;nbsp;from the Stone Age. &amp;nbsp;I'm sorry, it's not my intention to offend, but it's true. &amp;nbsp;I sometimes wonder how long SAP can continue, while the rest of the world races ahead with more and more sophisticated development tools? &amp;nbsp;Not to mention the inherent complexity and &lt;u&gt;true&lt;/u&gt; cost of ownership.&lt;br /&gt;&lt;br /&gt;That said, I can say SAP does what it says on the tin, often times with a half dozen SAP Consultants hovering over scratching their chins. &amp;nbsp;I have to admire these guys, namely because they have the patience and persistence to work with these types of systems. &amp;nbsp;I don't know if I could do what they do. &amp;nbsp;If the technology I'm working with becomes too restrictive or cumbersome or complex I simply find another. &amp;nbsp;Not so in the world of SAP. &amp;nbsp;What you see is what you get...warts and all.&lt;br /&gt;&lt;br /&gt;Enough of that. &amp;nbsp;In the end, after shedding blood, sweat and tears, we got there and it was a real team effort of two very different IT cultures.&lt;br /&gt;&lt;br /&gt;Now onto version 2...&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-1474390500278930284?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/1474390500278930284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=1474390500278930284' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/1474390500278930284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/1474390500278930284'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2010/09/update.html' title='Update'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-2985268016007088426</id><published>2010-05-03T19:03:00.000+01:00</published><updated>2010-05-03T19:03:39.418+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Some Observations...</title><content type='html'>Sorry for neglecting this blog, I'm in the throes of delivering a large mobile application, which has consumed all my waking hours.&lt;br /&gt;&lt;br /&gt;In our big push to get this product out the door, we've brought on-board additional developers. &amp;nbsp;Unfortunately, &amp;nbsp;they were not sufficiently grooved in to our architecture and coding standards. &amp;nbsp;As you can imagine, the result was less than expected. &amp;nbsp;One of the purposes of having a known architecture, in my opinion, is that it serves as a point of agreement within the team. &amp;nbsp;It defines where things are located, what function it performs, what its relationship is to other parts of the system. &amp;nbsp;In short, it establishes order and structure to a large number of projects and should bring about simplicity.&lt;br /&gt;&lt;br /&gt;When someone does not adhere to the agreed upon architecture they can be counted upon to introduce complexity. &amp;nbsp;To the uninitiated faced with a solution with 40-50 projects, all is complex. &amp;nbsp;Any changes they introduce will undoubted contain that complexity.&lt;br /&gt;&lt;br /&gt;On a similar note, regarding WPF....&lt;br /&gt;&lt;br /&gt;Whenever I see Xaml loaded up with Alignment, dimension attributes, etc, or StackPanels within StackPanels within Grids within StackPanels...ad nauseum, I know what the developer was experiencing. &amp;nbsp;He is using more and more settings and properties to force the Xaml to behave a certain way. &amp;nbsp;This brute force approach &lt;i&gt;always &lt;/i&gt;bloats your code and is &lt;i&gt;always &lt;/i&gt;inefficient. &amp;nbsp;If the UI does not bend to your will, the compulsion is to &lt;b&gt;add &lt;/b&gt;more settings - this is almost always a mistake.&lt;br /&gt;&lt;br /&gt;My golden rule when working with Xaml is: &lt;b&gt;&amp;nbsp;Less is More&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;If I'm faced with sorting out some misbehaving Xaml, the first thing I do is delete all the unnecessary properties and work with the core object. &lt;br /&gt;&lt;br /&gt;Anyway...just some observations. &amp;nbsp;I'm hoping to be more active on this blog once I've completed this current project.&lt;br /&gt;&lt;br /&gt;One new development effort I've been working on in the evening, is creating a Win 7 Media Center Add-in using Visual Studio 2010 and the Media Center SDK. &amp;nbsp;It's my first attempt, so I hope to have something worthwhile to report.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-2985268016007088426?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/2985268016007088426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=2985268016007088426' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2985268016007088426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2985268016007088426'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2010/05/some-observations.html' title='Some Observations...'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-6476096766499127662</id><published>2010-03-24T13:03:00.000Z</published><updated>2010-03-24T13:03:57.122Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Prism'/><title type='text'>New Composite/Pattern Forum</title><content type='html'>A new developer forum has been launched dedicated to composite technologies and design patterns, including Prism, MEF and MVVM. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.compositedevpatterns.com/forum.php"&gt;http://www.compositedevpatterns.com/forum.php&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-6476096766499127662?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/6476096766499127662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=6476096766499127662' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/6476096766499127662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/6476096766499127662'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2010/03/new-compositepattern-forum.html' title='New Composite/Pattern Forum'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-2191363104791587631</id><published>2010-02-10T15:29:00.011Z</published><updated>2010-02-10T19:43:45.171Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Prism'/><title type='text'>Prism Guidelines</title><content type='html'>&lt;span class="Apple-style-span" style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;Due to the number of projects and files which can make up a Prism solution, it is important to adhere to conventions which are intuitive and sensible. &amp;nbsp;Maintaining these conventions takes the guesswork out of working with Prism and makes navigating through a solution predictable.&lt;br /&gt;This document assumes a basic understanding of Prism, the Model-View-ViewModel (MVVM) design pattern, the Model-View-Controller (MVC) design pattern and Windows Presentation Foundation (WPF).&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Modules&lt;/span&gt;&lt;br /&gt;Prism requires that each module contain a class which implements &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;IModule&lt;/span&gt;. &amp;nbsp;This effectively serves as a stub, allowing Unity to load the module. &amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;IModule &lt;/span&gt;has an Initialize method that is often overridden and is used to register items in the container.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" src="http://www.gramann.co.uk/images/PrismModuleCode.png" /&gt;&lt;/div&gt;&lt;br /&gt;Avoid using the Initialize method to register the module’s items, instead create an entry in your &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;unity.config&lt;/span&gt; file. &amp;nbsp;It is easier to maintain and does not involve code.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Views&lt;/span&gt;&lt;/div&gt;&lt;div&gt;GOAL: To maintain a separation of UI and business logic.&lt;/div&gt;&lt;div&gt;It is rare that a UI requirement cannot be expressed using Xaml alone. &amp;nbsp;Effort should be made to eliminate any UI logic contained in the View.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Views always have a corresponding ViewModel.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;i&gt;Setting the ViewModel&lt;/i&gt;&lt;/div&gt;&lt;div&gt;Each View should contain a setter for its ViewModel, as shown below.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;img border="0" src="http://www.gramann.co.uk/images/PrismViewModelCode.png" /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;This property uses the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Microsoft.Practices.Unity.DependencyAttribute&lt;/span&gt;, which gets picked up by Unity and automatically set.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;&lt;br /&gt;Use of Styles&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Avoid defining custom styles which effect appearance within your module or view. &amp;nbsp;Instead, use styles defined in your application resource assembly. &amp;nbsp;If you need to modify a control’s behaviour through the use of a Trigger, use the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;BasedOn &lt;/span&gt;property of the Style, referencing the resource Style.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Always reference the resource Style by using a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;ComponentResourceKey &lt;/span&gt;defined in your Interfaces assembly.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Style="{StaticResource {ComponentResourceKey TypeInTargetAssembly={x:Type Resources:Styles}, ResourceId=DialogBorderStyleKey}}"&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;i&gt;Use of Converters&lt;/i&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Avoid excessive use of custom converters (&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;IValueConverter&lt;/span&gt;). &amp;nbsp;Often the same can be accomplished using Triggers or DataBinding. &amp;nbsp;Converters can act as “hidden” code-behind, making testing difficult. &amp;nbsp;Always look for a Xaml solution before resorting to the use of converters.&lt;/div&gt;&lt;br /&gt;&lt;i&gt;Naming Conventions&lt;/i&gt;&lt;br /&gt;&lt;table border="0" cellpadding="1" cellspacing="3"&gt;&lt;tbody&gt;&lt;tr&gt; &lt;td&gt;TYPE&lt;/td&gt; &lt;td&gt;NAMING RULE&lt;/td&gt; &lt;td&gt;EXAMPLE&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;View&lt;/td&gt; &lt;td&gt;&amp;lt;name&amp;gt;View &lt;/td&gt; &lt;td&gt;CustomerDetailView &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;Interface&lt;/td&gt; &lt;td&gt;I&amp;lt;name&amp;gt;View&lt;/td&gt; &lt;td&gt;ICustomerDetailView&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;ViewModels&lt;/span&gt;&lt;br /&gt;GOAL: To encapsulate all UI-related logic in a single, testable class.&lt;br /&gt;&lt;br /&gt;The ViewModel exists to serve the View, so use it. &amp;nbsp;Instead of using custom Converters do it in your ViewModel.&lt;br /&gt;&lt;br /&gt;Avoid passing the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;IUnityContainer&lt;/span&gt; (or an abstract version) in your ViewModel constructor. &amp;nbsp;This hides the actual dependency and makes testing difficult.&lt;br /&gt;&lt;br /&gt;Consider implementing &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;INotifyPropertyChanged &lt;/span&gt;on your ViewModel so your View can respond to changes in the ViewModel.&lt;/div&gt;&lt;br /&gt;&lt;i&gt;Naming Conventions&lt;/i&gt;&lt;br /&gt;&lt;table border="0" cellpadding="1" cellspacing="3"&gt;&lt;tbody&gt;&lt;tr&gt; &lt;td&gt;TYPE&lt;/td&gt; &lt;td&gt;NAMING RULE&lt;/td&gt; &lt;td&gt;EXAMPLE&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;ViewModel&lt;/td&gt; &lt;td&gt;&amp;lt;name&amp;gt;ViewModel &lt;/td&gt; &lt;td&gt;CustomerDetailViewModel &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;Interface&lt;/td&gt; &lt;td&gt;I&amp;lt;name&amp;gt;ViewModel&lt;/td&gt; &lt;td&gt;ICustomerDetailViewModel&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Interfaces&lt;/span&gt;&lt;br /&gt;GOAL: To provide contracts that define a public interface, separate from its implementation.&lt;br /&gt;&lt;br /&gt;Prism relies heavily on the use of interfaces. &amp;nbsp;All entities registered in the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;UnityContainer &lt;/span&gt;must include an interface and an entity that implements the interface.&lt;br /&gt;&lt;br /&gt;Do not include public interfaces in your implementation assemblies, as this defeats the purpose of decoupling interface from implementation.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;UserControls&lt;/span&gt;&lt;br /&gt;GOAL: To provide reusable UI elements independent of implementation.&lt;br /&gt;&lt;br /&gt;WPF UserControls differ from Views in that they do not have a related ViewModel.&lt;br /&gt;&lt;br /&gt;Consider adding DependencyProperties to your UserControl to take advantage of DataBinding and Triggers, this makes your UserControl more versatile and reusable.&lt;br /&gt;&lt;br /&gt;Avoid including binding to specific properties in your UserControl as this can greatly limit its reuse.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Naming Conventions&lt;/i&gt;&lt;br /&gt;&lt;table border="0" cellpadding="1" cellspacing="3"&gt;&lt;tbody&gt;&lt;tr&gt; &lt;td&gt;TYPE&lt;/td&gt; &lt;td&gt;NAMING RULE&lt;/td&gt; &lt;td&gt;EXAMPLE&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;UserControl&lt;/td&gt; &lt;td&gt;&amp;lt;name&amp;gt;UserControl &lt;/td&gt; &lt;td&gt;AddressUserControl &lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Services&lt;/span&gt;&lt;br /&gt;GOAL: To provide static, stateless business logic and functionality across domains.&lt;br /&gt;&lt;br /&gt;Services are normally registered in Unity as a singleton.&lt;br /&gt;&lt;br /&gt;It is best to think of Services as a static library of methods. &amp;nbsp;If state persistency is required consider using a Controller (MVC pattern).&lt;br /&gt;&lt;br /&gt;When consuming Services, avoid accessing them through IServiceLocator, instead explicitly use the service interface in your class constructor. &amp;nbsp;This makes for predictable testing and does not hide functionality or dependencies.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Naming Conventions&lt;/i&gt;&lt;br /&gt;&lt;table border="0" cellpadding="1" cellspacing="3"&gt;&lt;tbody&gt;&lt;tr&gt; &lt;td&gt;TYPE&lt;/td&gt; &lt;td&gt;NAMING RULE&lt;/td&gt; &lt;td&gt;EXAMPLE&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;Service&lt;/td&gt; &lt;td&gt;&amp;lt;name&amp;gt;Service &lt;/td&gt; &lt;td&gt;LoggingService &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;Interface&lt;/td&gt; &lt;td&gt;I&amp;lt;name&amp;gt;Service &lt;/td&gt; &lt;td&gt;ILoggingService &lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Events&lt;/span&gt;&lt;br /&gt;GOAL: To provide multicast notifications across domains.&lt;br /&gt;&lt;br /&gt;Note: The events referred to here are to be used by the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;EventAggregator&lt;/span&gt;, not standard .Net events.&lt;br /&gt;&lt;br /&gt;Do not define events in your implementation assemblies.  Since other assemblies will need to reference your event class placing them in an implementation assembly forces you to create a strong reference.  Instead, place it in your interface assembly or, if appropriate, a shared core assembly.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Naming Conventions&lt;/i&gt;&lt;br /&gt;&lt;table border="0" cellpadding="1" cellspacing="3"&gt;&lt;tbody&gt;&lt;tr&gt; &lt;td&gt;TYPE&lt;/td&gt; &lt;td&gt;NAMING RULE&lt;/td&gt; &lt;td&gt;EXAMPLE&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;Event&lt;/td&gt; &lt;td&gt;&amp;lt;name&amp;gt;Event&lt;/td&gt; &lt;td&gt;SaveCustomerEvent&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;Handler&lt;/td&gt; &lt;td&gt;&amp;lt;name&amp;gt;EventHandler &lt;/td&gt; &lt;td&gt;SaveCustomerEventHandler &lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Commands&lt;/span&gt;&lt;br /&gt;GOAL: To provide an input mechanism which allows for multiple and disparate sources to invoke the same command logic.&lt;br /&gt;&lt;br /&gt;Include command logic in your ViewModel, or if using a Controller you may want to defer execution to the Controller.&lt;br /&gt;&lt;br /&gt;Consider using a Command Behavior &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;AttachedProperty &lt;/span&gt;to convert events to Commands on controls that do not natively support &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;ICommand&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Naming Conventions&lt;/i&gt;&lt;br /&gt;&lt;table border="0" cellpadding="1" cellspacing="3"&gt;&lt;tbody&gt;&lt;tr&gt; &lt;td&gt;TYPE&lt;/td&gt; &lt;td&gt;NAMING RULE&lt;/td&gt; &lt;td&gt;EXAMPLE&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;Command&lt;/td&gt; &lt;td&gt;&amp;lt;name&amp;gt;Command&lt;/td&gt; &lt;td&gt;SaveCommand&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;Handler&lt;/td&gt; &lt;td&gt;&amp;lt;name&amp;gt;CommandExecute&lt;/td&gt; &lt;td&gt;SaveCommandExecute &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&amp;lt;name&amp;gt;CommandCanExecute &lt;/td&gt; &lt;td&gt;SaveCommandCanExecute &lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;Prediction and consistency go a long way in working with Prism.  Not subscribing to agreed upon conventions adds confusion and slows down development.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-2191363104791587631?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/2191363104791587631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=2191363104791587631' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2191363104791587631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2191363104791587631'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2010/02/prism-guidelines.html' title='Prism Guidelines'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-1447690612608739237</id><published>2010-01-25T21:40:00.001Z</published><updated>2010-01-25T21:42:34.841Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Prism'/><category scheme='http://www.blogger.com/atom/ns#' term='Xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Code Complexity and Prism</title><content type='html'>I've recently had to review a number of problem areas of a large Prism project. &amp;nbsp;In the course of review, I had a number of realisations regarding design patterns, WPF and code complexity. &amp;nbsp;We use MVVM and MVC design patterns throughout our project. &amp;nbsp;Not surprising, many of our problem areas were related to divergence from these patterns. &lt;br /&gt;&lt;br /&gt;In our implementation of MVVM we strive to have a complete decoupling of our Xaml views and any business logic. &amp;nbsp;So, finding views riddled with code-behind indicated a lack of understanding of:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The MVVM design pattern, or&lt;/li&gt;&lt;li&gt;The benefits of code separation&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Or as I was to find out, a limited understanding of Xaml. &amp;nbsp;The view in question utilised over ten custom converters. &amp;nbsp;Not that converters are inherently evil, however, these converters were being used where Triggers or Data Binding could have easily gotten the job done. &amp;nbsp;But, if one is unfamiliar with these, they tend to use techniques they &lt;i&gt;are &lt;/i&gt;familiar with -- in this case, IValueConverter. &amp;nbsp;Poor use of custom converters effectively becomes "hidden code-behind," and is difficult to debug and test. &lt;br /&gt;&lt;br /&gt;Additionally, I found the ViewModel being underused and misused, providing a sparse selection of high level properties for binding. &amp;nbsp;This, in part, prompted the excessive use of custom converters.&lt;br /&gt;&lt;br /&gt;The offending code-behind was an unusual solution brought about by a lack of Xaml know-how. &amp;nbsp; All of this code could have been expressed using Xaml. &amp;nbsp;Conclusion: Knowing a &lt;i&gt;little &lt;/i&gt;about Xaml can reek havoc on a well-structured Prism project.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;The hallmark of these decisions is code complexity, your first clue things have gone astray.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;After much refactoring, including the removal of all the custom converters, the code-behind and reworking the ViewModel, the whole area straighten out and was greatly simplified. &amp;nbsp;It was a prime example of the power and importance of design patterns in maintaining good form and structure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-1447690612608739237?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/1447690612608739237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=1447690612608739237' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/1447690612608739237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/1447690612608739237'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2010/01/code-complexity-and-prism.html' title='Code Complexity and Prism'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-8743404507468693883</id><published>2010-01-02T01:09:00.001Z</published><updated>2010-01-02T15:40:39.389Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Modularity'/><title type='text'>MEF Presentation Video</title><content type='html'>A work colleague recently turned me on to Microsoft's Managed Extensibility Framework (MEF) [see&amp;nbsp;&lt;a href="http://mef.codeplex.com/"&gt;http://mef.codeplex.com/&lt;/a&gt;]. &amp;nbsp;For anyone into Prism, MEF is worth a look. &amp;nbsp;Headed up by Glenn Block of Prism fame, MEF is an impressive technology.&lt;br /&gt;&lt;br /&gt;Glenn gives an hour long MEF presentation at PDC 09 at&amp;nbsp;&lt;a href="http://microsoftpdc.com/Sessions/FT24"&gt;http://microsoftpdc.com/Sessions/FT24&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In addition to an MEF orientation, there is a short presentation on MEF + Prism.&lt;br /&gt;&lt;br /&gt;Exciting stuff, in a geeky sort of way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-8743404507468693883?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/8743404507468693883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=8743404507468693883' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/8743404507468693883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/8743404507468693883'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2010/01/mef-presentation-video.html' title='MEF Presentation Video'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-2486838924045788787</id><published>2009-12-27T11:23:00.003Z</published><updated>2009-12-27T11:43:04.476Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Prism'/><category scheme='http://www.blogger.com/atom/ns#' term='Xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Prism Sample: Resources</title><content type='html'>An area of Prism development that often gets overlooked is the management of resources. &amp;nbsp;I mentioned in a previous blog that View reuse is unlikely, but that doesn't mean you should create unnecessary dependencies to a resource assembly.&lt;br /&gt;&lt;br /&gt;Similar&amp;nbsp;to modules, resource assemblies can have an&amp;nbsp;accompanying interface assembly. &amp;nbsp;This is done by defining ComponentResourceKeys in your interface assembly and using them as resource keys in your resource dictionary and in your Views.&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;public static class Styles&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public static ComponentResourceKey LargeTextStyleKey&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;get { return new ComponentResourceKey(typeof (Styles), "LargeTextStyle"); }&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;and in your Xaml...&lt;br /&gt;&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;textblock text="My Sample TextBlock Style"&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Style="{StaticResource {ComponentResourceKey TypeInTargetAssembly={x:Type Interfaces:Styles}, ResourceId=LargeTextStyleKey}}" /&amp;gt;&lt;/pre&gt;&lt;br /&gt;Taking this approach decouples your modules from the resource assembly. &amp;nbsp;The advantage to do this is not so much in the area of reuse, but more in the implementation of themes. &amp;nbsp;Any Views that require the use of a resource can simply refer to it by its ComponentResourceKey.&lt;br /&gt;&lt;br /&gt;Additionally, I would only have the Shell load the external resources, since the View modules are now unaware of the external resource. &amp;nbsp;The only draw back in doing this is you will lose your Visual Designer when editing your Xaml, because the designer cannot resolve the resource to render it.&lt;br /&gt;&lt;br /&gt;It is also worth setting up default styles based on control types, by using the control type as the resource key (e.g. {x:Type TextBlock}). &amp;nbsp;This does not require the use of ComponentResourceKeys. &lt;br /&gt;&lt;br /&gt;The area of theming WPF applications is a common one and there are a number of resources on CodePlex which address this area. &amp;nbsp;One example is the &lt;a href="http://razre.codeplex.com/"&gt;Razre WPF Framework&lt;/a&gt;, or you can build your own ThemeManager.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;I think this pretty much concludes the PrismSample articles. &amp;nbsp;This was meant as an introduction for developers starting out with Prism and to provide some guidelines in setting up a Prism solution. &amp;nbsp;I hope this was of some use. &amp;nbsp;I'm certain others will have differing opinions, and that's okay too. &amp;nbsp;I'm always on the hunt for new approaches and new ideas. &lt;br /&gt;&lt;br /&gt;I think Prism has a real future in WPF development. &amp;nbsp;Once you get into it and see the benefits, it changes how you think about and view WPF development; afterwards it is difficult &lt;i&gt;not &lt;/i&gt;to think and develop that way, which is a good thing.&lt;br /&gt;&lt;br /&gt;As always, comments/feedback welcome...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-2486838924045788787?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/2486838924045788787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=2486838924045788787' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2486838924045788787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2486838924045788787'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/12/prism-sample-resources.html' title='Prism Sample: Resources'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-8017105382422597829</id><published>2009-12-26T16:32:00.002Z</published><updated>2009-12-27T10:17:46.140Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Prism'/><title type='text'>Prism Sample: Services</title><content type='html'>In addition to Views and ViewModels, your Prism application will likely have one or more Services. &amp;nbsp;Per the CAL documentation, a service is defined as:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;A service is an object that provides functionality to other components in a loosely coupled way through an interface and is often a singleton&lt;/i&gt;.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is a fitting definition, but doesn't indicate belongs in a service or when something should be service. &amp;nbsp;Services reside outside the View-ViewModel pattern and provide functionality to anything that needs it. &amp;nbsp;In practice a service should address an area of business logic and have an appropriate name which describes the functionality it contains, like CustomerService or DataService, etc. &lt;br /&gt;&lt;/div&gt;&lt;div&gt;Avoid making a service a dumping ground for functionality you don't know where to put. &amp;nbsp;I tend to view services as static libraries of functionality, generally consisting of methods (think WCF Service Contracts). &amp;nbsp;My personal preference is to avoid storing state or exposing properties in services. &amp;nbsp;I don't use services to control workflow. &amp;nbsp;Instead I would implement a Controller to govern the workflow, and have the Controller consume the service.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On one Prism project, we would have regular design meetings where we would discuss where a given piece of functionality should reside. &amp;nbsp;The governing rule that came about, was that the ViewModel is directly concerned with the View and servicing the View; code that belongs in the ViewModel is there because of some requirement dictated by the View. &amp;nbsp;If that wasn't the case, we were probably looking at a general piece of business logic which likely belonged in a service (or Controller, if one existed).&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Following this line of thinking, we found more and more of our code moving to services, until we had a robust services layer, and a lean ViewModel which simply became a consumer of the services. &amp;nbsp;This approach prevented business logic getting lost or hidden in ViewModels. &amp;nbsp;It also supported our decision to separate out our services into their own assemblies, which I would highly recommend.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-8017105382422597829?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/8017105382422597829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=8017105382422597829' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/8017105382422597829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/8017105382422597829'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/12/prism-sample-services.html' title='Prism Sample: Services'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-209024403596054483</id><published>2009-12-20T12:17:00.003Z</published><updated>2009-12-20T12:20:26.091Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Prism'/><title type='text'>Prism Sample: Modules</title><content type='html'>Central to Prism is the concept of modules and modular design, therefore it's worth spending some time defining exactly what a module is, what it contains and what it shouldn't contain. &amp;nbsp;Per the Prism documentation:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;A module in the Composite Application Library is a logical unit in your application. Modules assist in implementing a modular design. These modules are defined in such a way that they can be discovered and loaded by the application at run time. Because modules are self-contained, they promote separation of concerns in your application. Modules can communicate with other modules and access services in a loosely coupled fashion. They reduce the friction of maintaining, adding, and removing system functionality. Modules also aid in testing and deployment&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Having worked on a number of Prism projects with a wide range of developers, each interpreting this from their own perspective and experience. &lt;br /&gt;&lt;br /&gt;Two of the guiding principles behind this are:&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;Single Responsibility Principle&lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns#Examples"&gt;Separation of Concerns&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;While most can agree on these principles, views differ on the depth and extent to which they are applied. &amp;nbsp;On one end of the spectrum we have the theorist, whose motivation may be to strictly adhere to these (some times with religious&amp;nbsp;fervor). &amp;nbsp;And on the other end we have the realist, who simply wants to build a working piece of software that meets the business requirements.&lt;br /&gt;&lt;br /&gt;The theorist looks beyond the business requirement, while the realist may argue that strict&amp;nbsp;allegiance&amp;nbsp;to these principles is outside the scope of the requirements. &amp;nbsp;Somewhere, somehow these views are resolved, usually by an architect or team lead; and the result usually falls somewhere in the middle.&lt;br /&gt;&lt;br /&gt;Personally, I fall in the middle, and maybe lean towards the realist. &amp;nbsp;I don't feel software development should be an academic exercise. &amp;nbsp;If someone entertains the idea of using a certain design pattern, I'm always interested in "what problem does this solve?" and "what does it buy me?" &amp;nbsp;Unacceptable answers are "because Fowler said so" or "because that's what the Prism team does". &lt;br /&gt;&lt;br /&gt;Enough of this, let's talk about modules...&lt;br /&gt;&lt;br /&gt;In an earlier post, I talked about creating an Advertising module for Blogger and said I would create the following modules:&lt;br /&gt;&lt;br /&gt;Blogger.Advertising.Interfaces&lt;br /&gt;Blogger.Advertising.Views&lt;br /&gt;Blogger.Advertising.ViewModels&lt;br /&gt;Blogger.Advertising.Services&lt;br /&gt;Blogger.Advertising.Services.Interfaces&lt;br /&gt;&lt;br /&gt;Some developers would be tempted to bundle these up into two assemblies:&lt;br /&gt;Blogger.Advertising&lt;br /&gt;Blogger.Advertising.Interfaces&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;storing their Views, ViewModels and Services in a single assembly.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;And I could be convinced of this. &amp;nbsp;It's certainly easier to maintain. &amp;nbsp;But I would argue that Views/ViewModels and Services are logically separate and warrant their own assemblies. &amp;nbsp;It's not inconceivable that another module or system could be a consumer of these services, without the need for Views or ViewModels.&lt;br /&gt;&lt;br /&gt;So, why separate out Views from ViewModels? &lt;br /&gt;&lt;br /&gt;I think it is somewhat idealistic to expect Views designed for Product A to be simply dropped into Product B (two different implementations). &amp;nbsp;In &lt;i&gt;theory&lt;/i&gt; this is possible, but in practice I've never seen it happen. &amp;nbsp;Here we get into areas of look and feel and layouts. &amp;nbsp;While we can do a lot to make a view generic and use themes and skins to alter its appearance, at the end of the day there is always going to be something different or required which makes the view unusable. &amp;nbsp;So why bother?&lt;br /&gt;&lt;br /&gt;I always assume my views are not going to be reusable; that they're part and parcel to a specific implementation. &amp;nbsp;My ViewModels, however, are completely reusable. &amp;nbsp;I would also argue that mocking up Views is far less time consuming than the creation of ViewModels.&lt;br /&gt;&lt;br /&gt;Regardless of what I think, your design decisions are going to be driven by a number of factors. &amp;nbsp;I think its important to consider all views and options, and decide which is suitable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-209024403596054483?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/209024403596054483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=209024403596054483' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/209024403596054483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/209024403596054483'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/12/prism-sample-modules.html' title='Prism Sample: Modules'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-7827384553259706346</id><published>2009-12-17T22:14:00.007Z</published><updated>2009-12-26T16:36:01.892Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Prism'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Prism Sample: Basic Concepts</title><content type='html'>As stated in my earlier post, this model solution attempts to illustrate how Prism and Unity are used, what is a module, what belongs in one and what doesn’t, the use of interfaces and design patterns.&lt;br /&gt;One of the most basic aspects of code organisation is knowing “what goes where”. &amp;nbsp;This is especially true with Prism projects. &amp;nbsp;Given you will likely have a dozen or more projects in your solution, it’s pretty important to sort out early on where things belong.&lt;br /&gt;I always try to minimise dependencies between my assemblies; and from time-to-time work-out what would be required to take a module and drop it into another application. &amp;nbsp;I’m always looking for ways to remove a dependency or decouple. &amp;nbsp;Even if I don’t have an immediate requirement to do that, as a general rule it’s a good idea.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Namespaces&lt;/b&gt;&lt;br /&gt;Picking the right naming convention for your projects and namespaces is pretty important. &amp;nbsp;I would spend ample time on this before embarking on any serious coding. &amp;nbsp;Maybe start with a prototype solution and put in some basic modules, a shell, some services, and their accompanying interfaces. &amp;nbsp;Play around with it and massage it into something you're comfortable with. &amp;nbsp;I think there is a natural order and organisation for these various projects and components.&lt;br /&gt;&lt;br /&gt;Microsoft's recommended namespace convention is:&lt;br /&gt;&lt;i&gt;Company.(Product|Technology)[.Feature][.Subnamespace]&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;/i&gt;for example, if I were creating an advertising module for Blogger, I would see something like...&lt;br /&gt;&lt;br /&gt;Blogger.Advertising.Interfaces&lt;br /&gt;Blogger.Advertising.Views&lt;br /&gt;Blogger.Advertising.ViewModels&lt;br /&gt;Blogger.Advertising.Services&lt;br /&gt;Blogger.Advertising.Services.Interfaces&lt;br /&gt;&lt;br /&gt;Microsoft has an excellent guideline for create .Net components at:&amp;nbsp;&lt;a href="http://msdn.microsoft.com/en-us/library/ms229026.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms229026.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Implementation vs Interface&lt;/span&gt;&lt;br /&gt;It's important to understand the difference between implementation and interface as it applies to modular development. &amp;nbsp;An interface is simply a public contract that defines an exposed surface. &amp;nbsp;Whereas, implementation deals with the deploy or realisation of the interface. &amp;nbsp;Interfaces do not contain business logic, &amp;nbsp;simply a definition of what something will look like once it is implemented.&lt;br /&gt;Prism and Unity makes heavy use of interfaces. &amp;nbsp;Interfaces are mapped to your implementation classes, either in code or in a configuration file.&lt;br /&gt;&lt;br /&gt;The following tips may be obvious to some, but I felt it was worth mentioning:&lt;br /&gt;&lt;br /&gt;Tip #1 - Do not create strong references to implementation assemblies.&lt;br /&gt;The exception to this are assemblies which comprise your Model. &lt;br /&gt;&lt;br /&gt;Tip #2 - Do not place anything in your implementation assemblies which forces other assemblies to create a strong reference.&lt;br /&gt;An example of this are Event classes. &amp;nbsp;You may have a module which publishes events, presumably to be subscribed to by other modules. &amp;nbsp;Do not include the Event class in your module assembly, instead place it in your module's interface assembly. &amp;nbsp;This makes it available to other assemblies though the interface reference. &amp;nbsp;Another common example are enumerations.&lt;br /&gt;&lt;br /&gt;Tip #3 - Do not register your implementation classes in the Module Initialize method.&lt;br /&gt;Registering classes in the Initialize method implies a specific implementation, but not all implementations. &amp;nbsp;Instead map your classes in a Unity configuration file.&lt;br /&gt;&lt;br /&gt;Tip #4 - Do not inject views into regions in the Module Initialize method.&lt;br /&gt;I never understood why anyone would want to do this, as it pretty much ruins any chance of reusing the module. &amp;nbsp;Instead, delegate view orchestration to another module, layer or layout manager.&lt;br /&gt;&lt;br /&gt;In fact, I can't think of good reason to put any code in the Module Initialize method.&lt;br /&gt;&lt;br /&gt;These tips address some hidden or covert implementation that commonly occurs in Prism development.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-7827384553259706346?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/7827384553259706346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=7827384553259706346' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/7827384553259706346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/7827384553259706346'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/12/prism-sample-basic-concepts.html' title='Prism Sample: Basic Concepts'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-4249047611051268060</id><published>2009-12-16T21:38:00.002Z</published><updated>2009-12-20T09:36:33.181Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Prism'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Prism Sample: Introduction</title><content type='html'>I had a request to post some sample code illustrating the use of Model-View-ViewModel pattern, Controllers and DelegateCommands. &amp;nbsp;This lead to the creation of a sample Prism solution. &amp;nbsp;An interesting exercise, since it gave me a chance to incorporate many of what I consider to be Prism best practices.&lt;br /&gt;I consider proper solution setup and organisation to be critical in working with Prism. &amp;nbsp;Mistakes made in this area often come back to haunt you. &amp;nbsp;There are many ways to organise your projects and code. &amp;nbsp;What is probably more important is pick a solution structure that everyone can agree with and stick with it. &amp;nbsp;A lack of agreement or ignorance of architecture can make team development a nightmare.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.gramann.co.uk/images/PrismSampleSolution.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.gramann.co.uk/images/PrismSampleSolution.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;I intend to write a series of postings detailing out what I consider to be areas of interest, and why I've organised things as I did.&lt;br /&gt;You can download the solution &lt;a href="http://www.gramann.co.uk/downloads/PrismSample.zip"&gt;here&lt;/a&gt;&amp;nbsp;(408kb). &amp;nbsp;You will require Visual Studio 2008 SP1. &amp;nbsp;I've stripped out all XML documentation and PDBs to keep the file size down.&lt;br /&gt;&lt;br /&gt;Please let me know if you run into any problems loading and running this solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-4249047611051268060?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/4249047611051268060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=4249047611051268060' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/4249047611051268060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/4249047611051268060'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/12/prism-sample-introduction.html' title='Prism Sample: Introduction'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-4141866399440636254</id><published>2009-12-03T22:08:00.001Z</published><updated>2009-12-03T22:10:15.029Z</updated><title type='text'>Some Agile thoughts...</title><content type='html'>Is it me, or have others found Agile development projects to be chaotic? &amp;nbsp;I will not profess to be an expert in this area. &amp;nbsp;I've been a developer on about four Agile-based projects, ranging from a handful of developers to a team of 20. &amp;nbsp;And, on the larger projects, the more Agile is pushed the more chaos seems to result. &lt;br /&gt;&lt;br /&gt;At worst it feels like a mad coding free-for-all, in an effort to meet development targets, while abandoning or ignoring coding conventions and best practices. &amp;nbsp;The idea being, "if we just get the cards done...the project will get done".&lt;br /&gt;&lt;br /&gt;I don't know how many times I've coded up a piece of functionality, written tests, etc., only to find weeks later, that someone else on the team "refactored" it, rendering it unusable. &amp;nbsp;One step forward, two steps back. &amp;nbsp;I've only really experienced this on Agile projects.&lt;br /&gt;&lt;br /&gt;Don't get me wrong, when I first encountered Agile I felt it had merit; and I still do. &amp;nbsp;But somewhere &amp;nbsp;between theory and execution the plot can get lost.&lt;br /&gt;&lt;br /&gt;I've always consider myself to be self-managing. &amp;nbsp;You give me a spec and I will methodically design, develop, test and document it to a finished product. &amp;nbsp;Maybe that's a bit old-school, but it got the job done.&lt;br /&gt;&lt;br /&gt;I would be interested in what others think about this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-4141866399440636254?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/4141866399440636254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=4141866399440636254' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/4141866399440636254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/4141866399440636254'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/12/some-agile-thoughts.html' title='Some Agile thoughts...'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-2513636106927631260</id><published>2009-10-20T17:43:00.000+01:00</published><updated>2009-10-20T17:43:17.333+01:00</updated><title type='text'>Win 7 Anti-Virus</title><content type='html'>For those of you running Win 7, you may have found it frustrating finding a suitable anti-virus product. &amp;nbsp;From experience, major players promoting Win 7 compatibility have proven anything but. &lt;br /&gt;A friend told me about Microsoft's new Security Essentials, which handles anti-virus, spyware and malware detection. &amp;nbsp;Best of all, it's free! &amp;nbsp;You can download it here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/security_essentials/default.aspx"&gt;http://www.microsoft.com/security_essentials/default.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Unlike other products, Security Essentials has a remarkably small footprint and has&amp;nbsp;negligible impact on performance. &amp;nbsp;Highly recommended.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-2513636106927631260?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/2513636106927631260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=2513636106927631260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2513636106927631260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2513636106927631260'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/10/win-7-anti-virus.html' title='Win 7 Anti-Virus'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-8888565262301803531</id><published>2009-10-16T16:04:00.002+01:00</published><updated>2009-11-03T12:03:16.017Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='UI Design'/><title type='text'>The Golden Age of UI Design</title><content type='html'>If you’ve been using computers as long as I have, you will be familiar with the evolution of Windows, from the humble 3.x on up to Win 7. A lot has changed over the years. As developers we have had to shift gears with each new incarnation. I’m probably dating myself if I mention Windows 3.1 and VB 3.0, but given the time, VB 3 practically ushered in RAD and allowed developers to create respectable UIs for the platform.&lt;br /&gt;&lt;br /&gt;With regards to the Windows User Interface, I can still remember the release of Windows 95 and all the fervour it created. There were developers and IT pros complaining bitterly about the change, citing their preference for 3.1 and their dislike for the new battleship grey 95. Those of us who embraced 95 in all its greyness, found new UI controls in our toolbox, most notably the Windows Common Controls. Enthusiasts, like myself, poured over Microsoft’s Windows 95 User Interface Guidelines book, a tome containing pixel by pixel specifications for creating standard Windows applications.&lt;br /&gt;&lt;br /&gt;If you were like me, this wasn’t enough. The next rung on the ladder was exploiting (some times questionable) Win API and GDI hacks, all in the attempt to enhance our application interfaces.&lt;br /&gt;&lt;br /&gt;The advent of .Net put an end to much of this. Designing WinForm applications certainly got easier and custom UIs no longer required slimy hacks. But, we were still limited to XP styled desktop applications.&lt;br /&gt;&lt;br /&gt;Concurrent with the advancements in Windows programming, the internet exploded and took centre stage. Graphic designers and illustrators sat side-by-side with application developers to create a new breed of user interface. User expectations were raised; not only did a UI have to be functional, but it had to be sexy as well.  Flash and Shockwave designers and developers expanded this further, raising the bar even higher.&lt;br /&gt;&lt;br /&gt;All of these advancements made WinForms look rather antiquated.&lt;br /&gt;&lt;br /&gt;All this was about to change with the release of .Net 3.0 and the introduction of Windows Presentation Foundation (WPF). For those unfamiliar with WPF, WPF is a XAML-based framework for creating Vista-styled desktop applications. Think XHTML meets WinForms and you’re almost there.&lt;br /&gt;&lt;br /&gt;Not only was WPF structurally different from its WinForms cousin, but included new resources and functionality WinForm developers only dreamed of. At last, desktop developers could create dynamic, sexy user interfaces that rivalled their contemporaries. The capabilities of WPF are so vast, that if you can dream it, you probably can build it.&lt;br /&gt;&lt;br /&gt;Gone are the stringent interface guidelines dictated by Microsoft; in its place are new collaborations between graphic designers and artists and software developers to produce user-centric software. All-in-all, this change is rather liberating. Where its headed I don’t know; will it be different from the past? Guaranteed.&lt;br /&gt;&lt;br /&gt;However, this is no Holy Grail. Designers and developers will still manage to produce repulsive, poorly designed software. But this is a chance we’re going to have to take.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-8888565262301803531?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/8888565262301803531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=8888565262301803531' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/8888565262301803531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/8888565262301803531'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/10/golden-age-of-ui-design.html' title='The Golden Age of UI Design'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-2556157687312378343</id><published>2009-10-07T13:58:00.005+01:00</published><updated>2009-12-20T09:36:06.091Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>Using OnValidate method in LINQ to SQL</title><content type='html'>If you are using LINQ to SQL you may have noticed the OnValidate partial method.&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;public partial class Person : INotifyPropertyChanging,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;INotifyPropertyChanged&lt;br /&gt;{&lt;br /&gt;     ...&lt;br /&gt;     partial void OnValidate(ChangeAction action);&lt;br /&gt;     ...&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;This method gets automatically called when the class participates in the DataContext SubmitChanges.&lt;br /&gt;&lt;br /&gt;When working with LINQ to SQL classes I prefer to keep my code generated classes separated from any modifications or customisations. &amp;nbsp;Normally, I will create a folder in my project called ExtendedClasses, there I can extend my business objects, giving them a &amp;lt;classname&amp;gt;.extended.cs file name. &amp;nbsp;This allows me to regenerate my business objects without fear of losing these customisations.&lt;br /&gt;&lt;br /&gt;So, in my extended class file I will include...&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;partial void OnValidate(ChangeAction action)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (action == ChangeAction.Insert)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//Do validation for inserts&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (action==ChangeAction.Insert ||&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;action==ChangeAction.Update)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//Do basic validation for inserts and updates&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;I avoid including any business rules in this class level validation, and stick to data related validation, such as field lengths, data ranges and required fields all based on my data model. &amp;nbsp;Any validation errors get raised by throwing an exception.&lt;br /&gt;Because the OnValidate method is private, you may want to include a public Validate method.&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;public void Validate()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (PersonId==Guid.Empty)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;OnValidate(ChangeAction.Insert);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;OnValidate(ChangeAction.Update);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;With the public Validate method I can validate my business object from the UI layer before passing it down to my services layer.&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;try&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;person.Validate();&lt;br /&gt;}&lt;br /&gt;catch (Exception e)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;MessageBox.Show(e.Message + "\n\n" + e.StackTrace);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return;&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-2556157687312378343?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/2556157687312378343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=2556157687312378343' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2556157687312378343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2556157687312378343'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/10/using-onvalidate-method-in-linq-to-sql.html' title='Using OnValidate method in LINQ to SQL'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-281644254691354778</id><published>2009-09-15T17:36:00.002+01:00</published><updated>2009-09-15T17:45:19.493+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>UK Post Code Search using LINQ to XML</title><content type='html'>I recently delved into working with UK Post Codes, including validation and searching. &amp;nbsp;This is not my first contact with this area, and in the past it has always involved large SQL tables or by using third-party products.&lt;br /&gt;&lt;br /&gt;This time, I was looking for something a bit more portable, like XML.&lt;br /&gt;&lt;br /&gt;I was able to find freeware downloads of UK Post Codes including their longitude and latitude, which was easily imported into a SQL Server database.&lt;br /&gt;&lt;br /&gt;I've created a class library called PostCodes.UK, which contains useful methods for validating post codes and determining which post codes fall within a given radial distance from a target post code. &amp;nbsp;All of the search and validation routines utilise LINQ to XML to query the XDocument.&lt;br /&gt;&lt;br /&gt;The class library relies on a PostCodes.xml file (supplied in the Test Harness project), which gets loaded as an XDocument. &amp;nbsp;I've included a small WPF Test Harness application which illustrates how this library is used.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.gramann.co.uk/images/UKPostCode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://www.gramann.co.uk/images/UKPostCode.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;To run this solution you will need Visual Studio 2008 SP1. &amp;nbsp;The source code is available &lt;a href="http://www.gramann.co.uk/downloads/UKPostCode.zip"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;For those interested in this area, there is an informative government page on &lt;a href="http://www.statistics.gov.uk/geography/postal_geog.asp#ps"&gt;Postal Geography&lt;/a&gt;, which explains the structure of the UK post codes. &amp;nbsp;You should be aware that UK post codes are always changing; however, if all you need is outward code resolution (e.g. PO6 ), chances are you can make do with public domain data.&lt;br /&gt;&lt;br /&gt;Another site with useful information is:&amp;nbsp;&lt;a href="http://www.easypeasy.com/guides/article.php?article=64"&gt;http://www.easypeasy.com/guides/article.php?article=64&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-281644254691354778?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/281644254691354778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=281644254691354778' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/281644254691354778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/281644254691354778'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/09/uk-post-code-search-using-linq-to-xml.html' title='UK Post Code Search using LINQ to XML'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-6328112957094867400</id><published>2009-09-10T18:46:00.000+01:00</published><updated>2009-09-10T18:46:56.328+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><title type='text'>Juan Enriquez Video</title><content type='html'>A friend recently sent me this link to a presentation made by Juan Enriquez on TED.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ted.com/talks/juan_enriquez_shares_mindboggling_new_science.html"&gt;http://www.ted.com/talks/juan_enriquez_shares_mindboggling_new_science.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enriquez has a unique viewpoint on recent global events, namely with the economy and technological advancements.  And he has a sense of humour which appears to be a rare commodity nowadays.&lt;br /&gt;&lt;br /&gt;Worth having a look.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-6328112957094867400?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/6328112957094867400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=6328112957094867400' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/6328112957094867400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/6328112957094867400'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/09/juan-enriquez-video.html' title='Juan Enriquez Video'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-4756893440935554343</id><published>2009-09-08T12:21:00.003+01:00</published><updated>2009-09-08T12:24:22.911+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Extension Methods'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>IsIn Extension Method</title><content type='html'>Another useful extension method I've found is the IsIn() method.  This is comes in handy when you have to test for enumeration values, for example:&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;public enum StatusValues&lt;br /&gt;{&lt;br /&gt; Open,&lt;br /&gt; Closed,&lt;br /&gt; Pending,&lt;br /&gt; Cancelled,&lt;br /&gt; Expired,&lt;br /&gt; Suspended&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;   ...&lt;br /&gt;&lt;br /&gt;if(myObject.Status == StatusValues.Closed ||&lt;br /&gt;   myObject.Status == StatusValues.Pending ||&lt;br /&gt;   myObject.Status == StatusValues.Expired)&lt;br /&gt;{  &lt;br /&gt;   ...&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;This can become cumbersome when testing for a number of values.&lt;br /&gt;&lt;br /&gt;The IsIn Extension Method simplifies this by taking a param list of values.&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;public static bool IsIn&amp;lt;T&amp;gt;(this T thisObject, params T[] values)&lt;br /&gt;{&lt;br /&gt;    if (thisObject != null &amp;amp;&amp;amp; values != null &amp;amp;&amp;amp; values.Length &amp;gt; 0)&lt;br /&gt;    {&lt;br /&gt;        foreach (var value in values)&lt;br /&gt;        {&lt;br /&gt;            if (thisObject.Equals(value))&lt;br /&gt;            {&lt;br /&gt;                return true;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return false;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Using this method, the above code can be rewritten as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;//using the IsIn Extension Method&lt;br /&gt;if(myObject.Status.IsIn(StatusValues.Closed,&lt;br /&gt;                        StatusValues.Pending,&lt;br /&gt;                        StatusValues.Expired))&lt;br /&gt;{&lt;br /&gt;   ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-4756893440935554343?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/4756893440935554343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=4756893440935554343' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/4756893440935554343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/4756893440935554343'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/09/isin-extension-method.html' title='IsIn Extension Method'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-7134881390384362471</id><published>2009-08-31T11:24:00.001+01:00</published><updated>2009-08-31T11:26:08.604+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Custom Control'/><title type='text'>Retro Flip Clock WPF Control</title><content type='html'>I know, I know...I last thing we need is another WPF Clock.&amp;nbsp; However, I recently went looking for a Flip Clock control and found surprisingly few - in fact, no usable ones.&amp;nbsp; So, it was back to the drawing board.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.gramann.co.uk/images/clock.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" lk="true" src="http://www.gramann.co.uk/images/clock.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Most of the attention has been on appearance, rather than functionality.&amp;nbsp; Feel free to modify and enhance.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;You can download the source code with sample project &lt;a href="http://www.gramann.co.uk/downloads/RetroClock.zip"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-7134881390384362471?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/7134881390384362471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=7134881390384362471' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/7134881390384362471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/7134881390384362471'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/08/retro-flip-clock-wpf-control.html' title='Retro Flip Clock WPF Control'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-2621727045972072930</id><published>2009-08-26T22:25:00.007+01:00</published><updated>2009-08-26T22:32:54.750+01:00</updated><title type='text'>Ethics and IT</title><content type='html'>I was recently offered employment at an investment bank in London, to which I respectfully declined.&amp;nbsp; The agent I was dealing with was somewhat surprised and wanted to know why.&amp;nbsp; I told him that I couldn't bring myself to work&amp;nbsp;for the banksters.&amp;nbsp; He was amused and replied "should my moral compass change..." the offer still&amp;nbsp;stood.&amp;nbsp; Interesting.&lt;br /&gt;&lt;br /&gt;I never considered my moral compass to be so fluid,&amp;nbsp;to actually consider assisting corporate&amp;nbsp;criminals&amp;nbsp;rape the&amp;nbsp;general public. What? Bigger? Better? Faster? More Efficiently?&amp;nbsp; I suppose I could find a way to justify it, but I couldn't see myself telling someone that is what I did for a living.&lt;br /&gt;&lt;br /&gt;I, like the next guy, seeks to be well rewarded for their work.&amp;nbsp; That doesn't automatically mean I do anything just because the rate is high.&amp;nbsp; I consider my services to be valuable and the products I produce hopefully forward the goals and aims of my client.&amp;nbsp; I mean, why do it at all if some good doesn't come out of it?&lt;br /&gt;&lt;br /&gt;I was discussing this point with some friends; where&amp;nbsp;do you&amp;nbsp;draw the line?&amp;nbsp; I knew where my line was.&amp;nbsp;&amp;nbsp;But it occurred to me that I shouldn't assume everyone has or is even aware of "The Line".&amp;nbsp; That there may be some people in the IT industry who will simply work on any project provided the price was right.&lt;br /&gt;&lt;br /&gt;Would you design software which assisted a pharmaceutical company to develop new mind-altering drugs which may result in suicide or mayhem?&lt;br /&gt;&lt;br /&gt;Or how about software which controls a guided missile that has an impressive kill-ratio?&amp;nbsp; (no, it's not the X-Box)&lt;br /&gt;&lt;br /&gt;No? Well somebody does.&lt;br /&gt;&lt;br /&gt;Now, these are not new questions.&amp;nbsp; While at engineering school we had a Technology and Ethics course,&amp;nbsp;but it&amp;nbsp;never delved into these types of issues (which may&amp;nbsp;have had something to do with the Department of Defence contracts).&amp;nbsp; Maybe no course can answer these questions, maybe only you can come up with an answer you can live with.&lt;br /&gt;&lt;br /&gt;So, in addition to the legalised drug pushers and the war-mongers we add a new villain (well, not new, just newly exposed) - the Banker, purveyors of economic chaos and destruction.&amp;nbsp; The respected banker, pillar of the community.&amp;nbsp; Lovely.&lt;br /&gt;&lt;br /&gt;If your love of banking is so strong, why not work for the &lt;a href="http://www.fsa.gov.uk/"&gt;Financial Services Authority&lt;/a&gt;?&amp;nbsp; I hear they're quite busy and need all the help they can get.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-2621727045972072930?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/2621727045972072930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=2621727045972072930' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2621727045972072930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/2621727045972072930'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/08/ethics-and-it.html' title='Ethics and IT'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-3938023326189547641</id><published>2009-08-25T12:32:00.010+01:00</published><updated>2009-08-25T12:50:34.100+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='Prism'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Layout Manager for Prism v2</title><content type='html'>One of the issues you may encounter when working on a Prism project is the management of regions and views within your application. While the RegionManager does an adequate job of managing regions, the orchestration of views and regions is pretty much left up to the developer. &lt;br /&gt;&lt;br /&gt;A common approach is to define string constants in a common infrastructure assembly and injecting views into regions using these constants. This gets the job done, but adds rigidity to your application. For applications which require multiple layouts, coordinating regions and views can be a bit tedious.&lt;br /&gt;&lt;br /&gt;One common approach I would not recommend is injecting your views in your module's Initialize method.&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;public void Initialize()&lt;br /&gt;{&lt;br /&gt;    var view = new MyView();&lt;br /&gt;    _Container.RegisterInstance&amp;lt;IMyView&amp;gt;(view);&lt;br /&gt;    _RegionManager.Regions[RegionNames.Shell].Add(view);&lt;br /&gt;}&lt;/pre&gt;This violates the encapsulation of the module, restricting the reuse of the module. &lt;br /&gt;&lt;br /&gt;On one project, we opted to create a "layout module". The sole purpose of this module was to load a layout UserControl into the Shell region of the main application window, and injecting the views into its own defined regions. Definitely a step in the right direction by decoupling the module views from the regions. The layout module was defined and loaded like any other module, but had to be the last module loaded due to its dependencies. One drawback to this approach was the increasing number of dependencies. The layout module had to reference all the infrastructure assemblies of the views it was required to manage.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;Still this solution felt a bit too purpose-built. And other issues quickly arose, such as multiple layout support.&amp;nbsp; Ideally we were looking for a complete decoupling of regions and views with the ability to dynamically load layouts as required.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;We quite liked the idea of using layout views, views whose sole purpose was to define regions, and providing no business or UI logic. But, the source and introduction of these views needed to be dynamic and flexible. The LayoutManager is my first attempt at tackling this issue. Its purpose is to dynamically manage one or more layout configurations for a Prism application.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;To compile and run the LayoutManager you will need Visual Studio 2008 SP1 and the latest version of the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=fa07e1ce-ca3f-4b9b-a21b-e3fa10d013dd&amp;amp;displaylang=en"&gt;Composite Application Guidance for WPF and Silverlight - February 2009&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;The solution is fairly standard Prism solution, consisting of an Infrastructure, Shell and Modules projects. For the sake of simplicity, I've only included a single Modules project, where normally there would be more.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;The LayoutManager maintains a collection of Layout objects, which define layout controls, along with the views that will reside in the layout.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;br /&gt;The LayoutManager is configured by a LayoutProvider specified in your app.config file.&lt;br /&gt;&lt;br /&gt;&amp;lt;section name="layoutProvider" type="Composite.Layout.Configuration.LayoutProviderSection, Composite.Layout"/&amp;gt;&lt;br /&gt;&lt;br /&gt;Currently, two providers are available: ConfigLayoutProvider and XamlLayoutProvider. Custom providers can be used by inheriting from LayoutProviderBase.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;strong&gt;ConfigLayoutProvider&lt;/strong&gt;&lt;br /&gt;Defines the LayoutManager in the app.config file as shown below:&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;layoutProvider name="ConfigLayoutProvider" type="Composite.Layout.Configuration.ConfigLayoutProvider, Composite.Layout"&amp;gt;&lt;br /&gt;    &amp;lt;layoutManager shellName="Shell" &amp;gt;&lt;br /&gt;      &amp;lt;layouts&amp;gt;&lt;br /&gt;        &amp;lt;layout name="FirstLayout" &lt;br /&gt;              filename="Layouts\FirstLayout.xaml" &lt;br /&gt;              fullname="First Layout" &lt;br /&gt;              isDefault="True"&lt;br /&gt;              description="This is the default layout" &lt;br /&gt;              thumbnailSource="pack://application:,,,/LayoutManager.Infrastructure;component/Resources/Images/layout1.png"&amp;gt;&lt;br /&gt;          &amp;lt;views&amp;gt;&lt;br /&gt;            &amp;lt;view typeName="LayoutManager.Infrastructure.IViewA, LayoutManager.Infrastructure" regionName="Left"  /&amp;gt;&lt;br /&gt;            &amp;lt;view typeName="LayoutManager.Infrastructure.IViewB, LayoutManager.Infrastructure" regionName="Right" /&amp;gt;&lt;br /&gt;            &amp;lt;viewModel typeName="LayoutManager.Infrastructure.IMenuViewModel, LayoutManager.Infrastructure" regionName="Menu"  viewProperty="View"/&amp;gt;&lt;br /&gt;          &amp;lt;/views&amp;gt;&lt;br /&gt;        &amp;lt;/layout&amp;gt;&lt;br /&gt;        ...&lt;br /&gt;          &amp;lt;/layouts&amp;gt;&lt;br /&gt;    &amp;lt;/layoutManager&amp;gt;&lt;br /&gt;&amp;lt;/layoutProvider&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;strong&gt;XamlLayoutProvider&lt;/strong&gt;&lt;br /&gt;Defines the LayoutManager in Xaml&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&amp;lt;layoutProvider name="XamlLayoutProvider"&lt;br /&gt;type="Composite.Layout.Configuration.XamlLayoutProvider, Composite.Layout"&lt;br /&gt;filename="Layouts\LayoutConfiguration.xaml"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;The source of the Xaml can be specified by type or by filename.&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;Layout:LayoutManager xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;br /&gt;                      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&lt;br /&gt;                      xmlns:Layout="clr-namespace:Composite.Layout;assembly=Composite.Layout"&lt;br /&gt;                      xmlns:Infrastructure="clr-namespace:LayoutManager.Infrastructure;assembly=LayoutManager.Infrastructure"&lt;br /&gt;                      ShellName="Shell"&amp;gt;&lt;br /&gt;    &amp;lt;Layout:LayoutManager.Layouts&amp;gt;&lt;br /&gt;        &amp;lt;Layout:Layout x:Name="FirstLayout"&lt;br /&gt;                       Fullname="First Layout"&lt;br /&gt;                       Filename="Layouts\FirstLayout.xaml"&lt;br /&gt;                       Description="This is the default layout"&lt;br /&gt;                       ThumbnailSource="pack://application:,,,/LayoutManager.Infrastructure;component/Resources/Images/layout1.png"&lt;br /&gt;                       IsDefault="True"&amp;gt;&lt;br /&gt;            &amp;lt;Layout:Layout.Views&amp;gt;&lt;br /&gt;                &amp;lt;Layout:ViewModel RegionName="Menu"&lt;br /&gt;                                  Type="{x:Type Infrastructure:IMenuViewModel}"&lt;br /&gt;                                  ViewProperty="View" /&amp;gt;&lt;br /&gt;                &amp;lt;Layout:View RegionName="Left"&lt;br /&gt;                             Type="{x:Type Infrastructure:IViewA}" /&amp;gt;&lt;br /&gt;                &amp;lt;Layout:View RegionName="Right"&lt;br /&gt;                             Type="{x:Type Infrastructure:IViewB}" /&amp;gt;&lt;br /&gt;            &amp;lt;/Layout:Layout.Views&amp;gt;&lt;br /&gt;        &amp;lt;/Layout:Layout&amp;gt;&lt;br /&gt; ...&lt;br /&gt;    &amp;lt;/Layout:LayoutManager.Layouts&amp;gt;&lt;br /&gt;&amp;lt;/Layout:LayoutManager&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;Each Layout contains a Views collection. The views collection accommodates both Views and ViewModels. The View specifies what view control is to be loaded and what region it is to be placed in. You can also set the visibility for the view. Use the ViewProperty of the ViewModel to specify the name of the property on your ViewModel which holds the View.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;The LayoutManager is loaded after all of the modules have initialized. In the Bootstrapper.cs:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;pre class="csharp" name="code"&gt;protected override void InitializeModules()&lt;br /&gt;{&lt;br /&gt;     base.InitializeModules();&lt;br /&gt;     InitializeLayoutManager();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private void InitializeLayoutManager()&lt;br /&gt;{&lt;br /&gt;     var layoutManager = LayoutConfigurationManager.LayoutManager;&lt;br /&gt;     layoutManager.Initialize(Container);&lt;br /&gt;     Container.RegisterInstance(layoutManager, new ContainerControlledLifetimeManager());&lt;br /&gt;     //parameterless LoadLayout loads the default Layout into the Shell&lt;br /&gt;     layoutManager.LoadLayout();&lt;br /&gt;}&lt;/pre&gt;The LayoutManager requires use of the Container. Once your layouts have been loaded, call the Initialize method passing in the container.&lt;br /&gt;&lt;br /&gt;Once that is done, you can register the LayoutManager in the container making it accessible to other modules.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Loading a Layout&lt;/strong&gt;&lt;br /&gt;Layouts are loaded by calling the LoadLayout method of the LayoutManager.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;LoadLayout()&lt;/em&gt;&amp;nbsp;loads the default layout in the Shell &lt;br /&gt;&lt;br /&gt;&lt;em&gt;LoadLayout(string layoutName)&lt;/em&gt; loads the named layout in the Shell &lt;br /&gt;&lt;br /&gt;The MenuViewModel.cs illustrates the use of LoadLayout:&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;private void LayoutCommandExecute(ILayout layout)&lt;br /&gt;{&lt;br /&gt;var layoutManager = _Container.Resolve&amp;lt;ILayoutManager&amp;gt;(); &lt;br /&gt;layoutManager.LoadLayout(layout.Name);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The basic sequence of loading a layout is:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;If there is a current layout, remove it from the RegionManager. &lt;/li&gt;&lt;li&gt;Clear out any controls that were bound to any regions. This step is necessary otherwise you will get an InvalidOperationException ("This control is being associated with a region, but the control is already bound to something else") when you try to reload it in the future. Currently, the LayoutManager only supports ItemsControls, ContentControls and Panels using the RegionManager.RegionName attached property. &lt;/li&gt;&lt;li&gt;Add the new Layout Control to the RegionManager. &lt;/li&gt;&lt;li&gt;Register any Regions contained within the Layout Control. &lt;/li&gt;&lt;li&gt;Load any views associated with the new layout. &lt;/li&gt;&lt;/ol&gt;&lt;strong&gt;Events&lt;/strong&gt;&lt;br /&gt;There are several events raised by the LayoutManager:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;LayoutManagerInitializedEvent&lt;/em&gt;&amp;nbsp;raised at the end of Initialize (see MenuViewModel.cs for an example of subscribing to this event) &lt;/li&gt;&lt;li&gt;&lt;em&gt;LayoutLoadingEvent&lt;/em&gt;&amp;nbsp;raised at the beginning of LoadLayout &lt;/li&gt;&lt;li&gt;&lt;em&gt;LayoutLoadedEvent&lt;/em&gt;&amp;nbsp;raised at the end of LoadLayout &lt;/li&gt;&lt;li&gt;&lt;em&gt;LayoutUnloadingEvent&lt;/em&gt;&amp;nbsp;raised before the current layout is about to be unloaded &lt;/li&gt;&lt;li&gt;&lt;em&gt;LayoutUnloadedEvent&lt;/em&gt;&amp;nbsp;raised after the current layout has been unloaded &lt;/li&gt;&lt;/ul&gt;All of these events are published through the EventAggregator.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Limitations&lt;/strong&gt;&lt;br /&gt;Currently there are several limitations with the LayoutManager, these are:&lt;br /&gt;LayoutManager currently only supports UserControls as layout controls. There is also the basic assumption that your application main window has a single region defined, where layout controls are injected. Regions must be defined in XAML using the RegionManager.RegionName attached property.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Other Considerations&lt;/strong&gt;&lt;br /&gt;While the LayoutManager does decouple the regions from the views, it does not entirely do away with string-based region names. Dynamic manipulation of regions and views in code will still rely on region names (see the AddCommandExecute method in MenuViewModel.cs on how to programmatically add layouts). And region name attributes must match actual region names in the Layout control. &lt;br /&gt;&lt;br /&gt;A possible approach to addressing this dependency may be to introduce a RegionType enumeration such as Top, Bottom, Left, Right, Center, StatusBar, Menu, Toolbar, etc. In which case, the LayoutManager could resolve these regions regardless of string names.&lt;br /&gt;&lt;br /&gt;I have not tested the LayoutManager in all possible scenarios, such as nested layouts and custom RegionAdapters, or with Silverlight.&lt;br /&gt;&lt;br /&gt;You can download the LayoutManager source code &lt;a href="http://www.gramann.co.uk/downloads/LayoutManagerSourceCode.zip"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-3938023326189547641?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/3938023326189547641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=3938023326189547641' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/3938023326189547641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/3938023326189547641'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/08/layout-manager-for-prism-v2.html' title='Layout Manager for Prism v2'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-5593445388474729140</id><published>2009-08-24T13:58:00.007+01:00</published><updated>2009-09-10T18:37:06.196+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Extension Methods'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>StringBuilder Extensions</title><content type='html'>I recently had a requirement to&amp;nbsp;modify some&amp;nbsp;Html-based reports.&amp;nbsp; These reports were built up in code using a StringBuilder, along with report content data.&amp;nbsp; The plus-point is that it worked and delivered the desired reports.&amp;nbsp; On the downside, the code was tedious and verbose.&amp;nbsp; For example:&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;StringBuilder stringBuilder = new StringBuilder();&lt;br /&gt;stringBuilder.Append("&amp;lt;TABLE id=\"Table2\" width=\"100%\"&amp;gt;");&lt;br /&gt;stringBuilder.Append("&amp;lt;TR style=\"page-break-inside : avoid\"&amp;gt;&amp;lt;TD class=\"reportHeaderTitle\" &amp;gt;" + ResourceManager.GetString("ReportTitle", culture) + "&amp;lt;/TD&amp;gt;&amp;lt;/TR&amp;gt;");&lt;br /&gt;stringBuilder.Append("&amp;lt;TR&amp;gt;&amp;lt;TD style=\"PADDING-LEFT: 5px; PADDING-BOTTOM:10px\" width=\"100%\"&amp;gt;");&lt;br /&gt;stringBuilder.Append("&amp;lt;TABLE id=\"Table2\" width=\"100%\"&amp;gt;");&lt;br /&gt;stringBuilder.Append("&amp;lt;TR style=\"page-break-inside : avoid\"&amp;gt;&amp;lt;TD class='reportHeader' align=\"center\" width=\"50%\"&amp;gt;" + ResourceManager.GetString("ReportSubTitle", culture) + "&amp;lt;/TD&amp;gt;");&lt;br /&gt;stringBuilder.Append("&amp;lt;TD class='reportHeader' align=\"center\" width=\"50%\"&amp;gt;" + ResourceManager.GetString("ReportResults", culture) + "&amp;lt;/TD&amp;gt;&amp;lt;/TR&amp;gt;");&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I was staring at 1000s of lines of code like this.&amp;nbsp; After a while it was all a blur.&lt;br /&gt;&lt;br /&gt;My first impulse was to subclass the StringBuilder and build up some Html-specific methods.&amp;nbsp; Unfortunately, the StringBuilder class is sealed.&amp;nbsp;&amp;nbsp;&amp;nbsp;I also looked at the HtmlTextWriter class, a class primarily used when working with custom server controls.&amp;nbsp; But, this seemed overkill for the purpose.&amp;nbsp; I just needed a clean way to build-up an Html string in code.&lt;br /&gt;&lt;br /&gt;I&amp;nbsp;then turned to writing a set of Extensions Methods&amp;nbsp;to provide this functionality.&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;#region Using Directives&lt;br /&gt;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;namespace Common.Extensions&lt;br /&gt;{&lt;br /&gt;    public static class StringBuilderExtensions&lt;br /&gt;    {&lt;br /&gt;        public static void BeginTable(this StringBuilder stringBuilder)&lt;br /&gt;        {&lt;br /&gt;            stringBuilder.Append("&amp;lt;table&amp;gt;");&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public static void EndTable(this StringBuilder stringBuilder)&lt;br /&gt;        {&lt;br /&gt;            stringBuilder.Append("&amp;lt;/table&amp;gt;");&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public static void BeginRow(this StringBuilder stringBuilder)&lt;br /&gt;        {&lt;br /&gt;            stringBuilder.Append("&amp;lt;tr&amp;gt;");&lt;br /&gt;        }&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;In refactoring the code I first pulled all of the inline styles out and into style classes.&amp;nbsp; Then I began migrating the existing code over to use the new extension methods.&amp;nbsp; The refactored code looks something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;var stringBuilder = new StringBuilder();&lt;br /&gt;stringBuilder.HorizontalRule();&lt;br /&gt;stringBuilder.BeginH2();&lt;br /&gt;stringBuilder.Append(ResourceManager.GetString("ReportTitle", _Culture));&lt;br /&gt;stringBuilder.EndH2();&lt;br /&gt;&lt;br /&gt;stringBuilder.BeginTable();&lt;br /&gt;stringBuilder.BeginTHead();&lt;br /&gt;stringBuilder.BeginRow();&lt;br /&gt;stringBuilder.BeginCell("reportHeader");&lt;br /&gt;stringBuilder.Append(ResourceManager.GetString("ReportSubTitle", _Culture));&lt;br /&gt;stringBuilder.EndCell();&lt;br /&gt;stringBuilder.BeginCell();&lt;br /&gt;stringBuilder.Append(ResourceManager.GetString("ReportResults", _Culture));&lt;br /&gt;stringBuilder.EndCell();&lt;br /&gt;stringBuilder.EndRow();&lt;br /&gt;stringBuilder.EndTHead();&lt;br /&gt;...&lt;/pre&gt;In it's current state, the extensions only supply the Html tags that were required, but could easily be expanded to support all of the commonly used tags.&amp;nbsp; I personally find this refactored code much easier to read and maintain.&lt;br /&gt;&lt;br /&gt;You can download the StringBuilderExtensions.zip &lt;a href="http://www.gramann.co.uk/downloads/StringBuilderExtensions.zip"&gt;here&lt;/a&gt;.&lt;br /&gt;I hope this may be of some use.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-5593445388474729140?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/5593445388474729140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=5593445388474729140' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/5593445388474729140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/5593445388474729140'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/08/stringbuilder-extensions.html' title='StringBuilder Extensions'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-4940759870455577199</id><published>2009-08-24T10:46:00.007+01:00</published><updated>2009-08-25T08:51:37.276+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Extension Methods'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Extension Method Usage</title><content type='html'>If you are like me, once you have the Big Extension Method Realisation you tend to go overboard on their use.&amp;nbsp; This is eventually followed by the more practical Extension Method &lt;em&gt;Usage&lt;/em&gt; Realisation.&amp;nbsp; This second realisation puts Extension Methods into perspective.&lt;br /&gt;&lt;br /&gt;For example, you could quite easily create an extension method like this:&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;public static bool IsNull(this object thisObject)&lt;br /&gt;{&lt;br /&gt;return thisObject == null;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This method can replace&lt;br /&gt;if(myObject==null) &lt;br /&gt;&lt;br /&gt;with...&lt;br /&gt;&lt;br /&gt;if(myObject.IsNull())&lt;br /&gt;&lt;br /&gt;But is it worth it?&amp;nbsp; Is there anything wrong with myObject==null?&amp;nbsp; Of course not.&amp;nbsp; So why change it or replace it with an extension method.&amp;nbsp; It adds no new functionality, just a change of syntax.&lt;br /&gt;Additionally, you will often collect your extension methods and place them in a common assembly.&amp;nbsp; Use of the above extension method creates an dependency on this assembly.&amp;nbsp; But what does it buy you?&amp;nbsp; I would argue, nothing.&amp;nbsp; So, lose it.&lt;br /&gt;From my experience in working with extension methods, I've found the most valuable to be methods that supply missing functionality or ones that encapsulate often repeated code.&amp;nbsp; &lt;br /&gt;An example of this is checking if a collection contains any items, kind of like a cousin of String.IsNullOrEmpty.&amp;nbsp; For me, this is a prime candidate for an extension method, and should have been included in the IList interface (IMHO).&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharp" name="code"&gt;public static bool HasItems(this IList collection)&lt;br /&gt;{&lt;br /&gt;return collection != null &amp;amp;&amp;amp; collection.Count &amp;gt; 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;So we reduce &lt;br /&gt;if(myCollection!=null &amp;amp;&amp;amp; myCollection.Count&amp;gt;0) &lt;br /&gt;&lt;br /&gt;to a clean and simple&lt;br /&gt;&lt;br /&gt;if(myCollection.HasItems())&lt;br /&gt;&lt;br /&gt;I know there is not a shortage of resources on the web regarding extension methods.&amp;nbsp; However, after working with them for a few years, I have managed to collect a few "must have" extension methods, which I will be posting over time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-4940759870455577199?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/4940759870455577199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=4940759870455577199' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/4940759870455577199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/4940759870455577199'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/08/extension-methods-if-you-are-like-me.html' title='Extension Method Usage'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-4872359364337028962</id><published>2009-08-24T10:12:00.001+01:00</published><updated>2009-08-24T14:17:06.842+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>CodeProject Articles</title><content type='html'>I have authored two CodeProject articles on WPF and Prism.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;WPF Gadget Container Control&lt;/em&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/KB/WPF/WPFGadget.aspx"&gt;http://www.codeproject.com/KB/WPF/WPFGadget.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Layout Manager for Prism v2&lt;/em&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/KB/WPF/PrismLayoutManager.aspx"&gt;http://www.codeproject.com/KB/WPF/PrismLayoutManager.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you are interested in this area of .Net, check them out and let me know what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-4872359364337028962?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/4872359364337028962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=4872359364337028962' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/4872359364337028962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/4872359364337028962'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/08/codeproject-articles-i-have-authored.html' title='CodeProject Articles'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31900010.post-7511871752785544247</id><published>2009-08-24T09:33:00.001+01:00</published><updated>2009-08-24T14:17:29.351+01:00</updated><title type='text'>Introduction</title><content type='html'>This is my second blogging attempt, the first failed due to blogger's guilt. Now I have a renewed sense of purpose and dedication and have allocated time to make this a respectable blog. Round Two...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31900010-7511871752785544247?l=rgramann.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rgramann.blogspot.com/feeds/7511871752785544247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31900010&amp;postID=7511871752785544247' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/7511871752785544247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31900010/posts/default/7511871752785544247'/><link rel='alternate' type='text/html' href='http://rgramann.blogspot.com/2009/08/this-is-my-second-blogging-attempt.html' title='Introduction'/><author><name>rgramann</name><uri>http://www.blogger.com/profile/17600180313517679404</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
