Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Wednesday, 29 January 2014

Alternating Rows with the LongListSelector

If you are familiar with the LongListSelector control in Windows Phone, you may have noticed that it does not natively support alternating row styles.  With regards to list items, you’re left with the ItemTemplate to determine the layout and appearance of your list items.

To change the background colour of your items, one possible workaround is to use a converter to evaluate a property on your bound item, and alternate between two sets of brushes.  I’ve created an AlternatingRowConverter to do just that.




Here, the converter is expecting an integer value and by doing a simple modulus we can switch between two SolidColorBrushes, which have been defined as public properties.
Here’s what our xaml looks like:


Notice that the PrimaryRowBrush and AlternateRowBrush can be defined in a number of ways, either by named value or hex, or creating the brush directly.

Within the LongListSelector.ItemTemplate we use a StackPanel to house the item.  The Background property of the StackPanel is bound to the Index property of a business object called Fruit.  The Converter takes the integer value and returns either the PrimaryRowBrush or AlternateRowBrush.
And here’s the result:


You can download the source code here.

Sunday, 13 January 2013

M25: My First WP8 App - Part III

Once I determined what my version 1.0 feature set would be I next started work on the UI.  I know other developers who approach it differently, starting with a data model and working their way to the UI.  I've done both and I prefer starting with the UI and letting that drive the model.  This is more of a needs-based approach.  The best approach is the one that works for you.

During this phase I did quite a bit of prototyping and experimenting.  At one stage I envisioned having a clock-like representation of the circular M25, with each junction positioned in its relative position along the rim.  While it was pretty cool, there were usability issues due to limited screen real estate and the number of junctions on the circle.  Unfortunately I had to abandon what was going to be a centerpiece control for my app.

Instead I went with a more conventional edit screen and list picker.

The governing reason for this decision was usability.  It was simple and intuitive.

Early on I had decided to adopt a colour-coded status (red, amber and green) to indicate traffic status.  I wanted to keep things simple and not complicate the user experience.  I wanted the user to simply glance at the screen and get an immediate feel for the traffic conditions.

After reviewing some sample data from the Highways Agency related to the types of incident reports, I came up with this:


The result is the My Routes page:

I chose to use the Cambria font as a title font instead of the standard Segoe WP, more for aesthetic reasons. The same colour convention was used throughout the app, as in the Junction List page:

Another temptation was to incorporate the built-in WP8 maps functionality.  Again, my objective was not to create a SatNav application or journey planner, but to keep the app focus on the current traffic conditions of the M25.  That said, there was a point where I felt access to maps was relevant and potentially useful.  On the Junction Detail page I display a small map snapshot along with traffic data for the junction.  From here the user can jump to WP8 Maps using this location.

That's pretty much the summary for the UI development.  A lot of experimentation occurred to arrive at this point.  Some developers may view the Modern UI (formerly Metro) as being simple or easy to design, and in some respects it is.  I don't claim to be an expert in Modern UI design or that my app is a standard reference.  I do think that working with the Modern UI shifts the emphasis of design.  Instead of making something look pretty or have a wow-factor, the designer is really focused on information and how best to express that on the screen.  To some degree our GUI design legacy leans toward complex UIs.  Modern UI is forcing us to revisit and rethink user experience, stripping things back to the basics.  This is an interesting process, and ultimately a rewarding one.


M25: My First WP8 App - Part II

For anyone considering developing a mobile app, whether for WP or others, I think having a well-defined purpose is the first step.  After all, the app is supposed to do something, right?  I may be stating the obvious, but there are some subtleties here worth recognising.  Initially I wanted to incorporate real-time traffic speed, CCTV cameras, Twitter feeds, etc.  While these are perfectly valid features, including them in the first cut may not fit in my timeline.  So, I stripped things down to the basics, which included:

  • Pull down current traffic information
  • Pull down known planned events related to the M25
  • Allow the user to define routes
  • Display status information
  • Use a background agent to display current data in a Live Tile

So, this was my list of core functionality or deliverables.  Regardless of any extra bells and whistles, the app had to solidly deliver this set of features.  As well as naming those items "to do", you should also be aware of what "not to do".  I set a personal target to get this done within the month of December.  Given my time constraints I felt this was doable.  A lot of the other ideas I had are still valid, but can be added to my roadmap for future versions.

I created a new solution in Visual Studio 2012.  To my solution I added a Windows Phone application targeting Windows Phone 8.0 called M25.WP8; a Windows Phone class library called M25.Data; and a Windows Phone Scheduled Task Agent called M25.Agent.


I knew from my feature set that this was the minimal architectural requirements.  M25.Data would do all the data management and processing.  While the M25.WP8 phone application tended to the UI/UX requirements and M25.Agent was dedicated to running in the background and updating the Live Tile.  Not shown in the diagram is the reference between M25.Agent and M25.WP8; to get your Task Agent to be recognised by Windows Phone it has to be associated with an application so it gets included in your xap.  Pretty straightforward.




 

M25: My First WP8 App - Part I

I will be publishing my first Windows Phone 8 into the Windows Store in the next day or so.  It is called M25.  For those outside the UK, the M25 is the London Orbital motorway.  Like a huge wagon wheel, the M25 circles London with spokes running to the heart of the city.  It is the UK's busiest motorway, and some say in all of Europe.

So why create an app for a motorway?

For three years I traveled the M25 every day, and every time you plan to get on it you wonder what state it's in.  My carpooling passenger and I would have a routine when leaving the office; checking various web sites to determine whether we should even get on the M25.  Anyone who frequents the M25 has their own horror story of spending hours on the M25 parking lot.

I know what you're going to say - but, surely any decent SatNav app is going to tell you the traffic conditions of the M25 - and you would be correct.  But, the point is, I know how to get home.  And maybe I don't want to tie my phone up running Nokia Drive, when all I really want to know is happening on the M25.

What I really want is a lightweight app that is going to give me current, accurate traffic conditions for my section of the motorway.  I don't want to have to wade through traffic data about other motorways or even other parts of the M25 (the M25 is about 115 miles in length).  I'm just interested in what is happening between junctions 13 and 6.  So, I'm looking for the ability to filter traffic data from the volume of information pushed out by the Highways Agency.

Here's what I came up with:
So, that was the motivation for creating this app.  In subsequent articles I will discuss some of the issues I encountered, both technically and functionality.

I'm fully aware that this app is not going to set the world afire.  Developing it was as much for my benefit as it may be for others.  That said, I do think that it may prove valuable to those who wrestle with the M25 on a daily basis.

Thursday, 7 April 2011

MVVM Revisited

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.  Working with MVVM by itself, is relatively straightforward.   Combine it with other patterns, such as MVC and IoC, and things can get complicated.

Here is a common implementation of MVVM:

This example also utilises a CustomerController along with some services, all of which are supplied by the “Model”.  If you’ve worked with Prism you’ll probably recognise this rather unorthodox implementation of MVC, something I’ve never been comfortable with.  Injecting a controller into a ViewModel seems backasswards to me.  I would prefer to have the Controller be aware of the ViewModel and indirectly control/manage the Views.

Aside from being awkward, this approach does work.  But don’t expect your modules to be “modular”.  Sure, within your solution it will have the appearance of being a module, but it won’t very portable.  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.

So, what is modularity without portability?  Without portability, modularity is reduced to a code organisation concept.  

Looking over this situation it occurred to me that the injection of dependencies in the ViewModel was pretty much unrestrained.  If the ViewModel needed it, just add another parameter to the constructor.  The entire Model was wide-open for consumption, provided it was registered with Unity.  Needless to say, this leads to greater and greater consumption, until finally the ViewModel is entrenched in implementation.

When viewed as a microcosm, MVVM can act like a tiered architecture.  And tiered architectures are great for scalable server applications, but pretty much ruin any hopes of portability.  

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.  So, why not give it exactly what it needs – and no more.

One way to accomplish this through the introduction of a custom Model class:

Here the CustomerModel class defines exactly what the ViewModel demands of the Model.  In effect, it is a subset of the Model and is specific to that ViewModel.   It’s the ViewModel’s shopping list – “if you’re going to use me, this is my list of demands”.  It is now up to the implementer to provide this functionality – which is where the responsibility belongs.

With this approach the ViewModel has now been liberated and all of the “dependencies” removed.  Service methods have been replaced with delegates.  The ICustomerService can reside in the module itself, effectively making the CustomerModule a self-contained, standalone assembly.

A side benefit is that the View now contains no code-behind and is no longer dependent on the ViewModel interface.

While working through this I’ve created a new Prism sample solution, which includes a CustomerModule and an OrdersModule, Implementation project and a Shell.  I have reduced the module dependency down to a single Core assembly.  The Implementation project contains controllers, core services, a persistence manager, etc.  It knows about the modules and can orchestrate the workflow and manage the views.  The controllers “wire up” the Model and inject them into the ViewModels.   

At the moment, CustomerModule + Core is about as portable as it gets.

Monday, 3 May 2010

Some Observations...

Sorry for neglecting this blog, I'm in the throes of delivering a large mobile application, which has consumed all my waking hours.

In our big push to get this product out the door, we've brought on-board additional developers.  Unfortunately,  they were not sufficiently grooved in to our architecture and coding standards.  As you can imagine, the result was less than expected.  One of the purposes of having a known architecture, in my opinion, is that it serves as a point of agreement within the team.  It defines where things are located, what function it performs, what its relationship is to other parts of the system.  In short, it establishes order and structure to a large number of projects and should bring about simplicity.

When someone does not adhere to the agreed upon architecture they can be counted upon to introduce complexity.  To the uninitiated faced with a solution with 40-50 projects, all is complex.  Any changes they introduce will undoubted contain that complexity.

On a similar note, regarding WPF....

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.  He is using more and more settings and properties to force the Xaml to behave a certain way.  This brute force approach always bloats your code and is always inefficient.  If the UI does not bend to your will, the compulsion is to add more settings - this is almost always a mistake.

My golden rule when working with Xaml is:  Less is More.

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.

Anyway...just some observations.  I'm hoping to be more active on this blog once I've completed this current project.

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.  It's my first attempt, so I hope to have something worthwhile to report.

Monday, 25 January 2010

Code Complexity and Prism

I've recently had to review a number of problem areas of a large Prism project.  In the course of review, I had a number of realisations regarding design patterns, WPF and code complexity.  We use MVVM and MVC design patterns throughout our project.  Not surprising, many of our problem areas were related to divergence from these patterns.

In our implementation of MVVM we strive to have a complete decoupling of our Xaml views and any business logic.  So, finding views riddled with code-behind indicated a lack of understanding of:

  1. The MVVM design pattern, or
  2. The benefits of code separation

Or as I was to find out, a limited understanding of Xaml.  The view in question utilised over ten custom converters.  Not that converters are inherently evil, however, these converters were being used where Triggers or Data Binding could have easily gotten the job done.  But, if one is unfamiliar with these, they tend to use techniques they are familiar with -- in this case, IValueConverter.  Poor use of custom converters effectively becomes "hidden code-behind," and is difficult to debug and test.

Additionally, I found the ViewModel being underused and misused, providing a sparse selection of high level properties for binding.  This, in part, prompted the excessive use of custom converters.

The offending code-behind was an unusual solution brought about by a lack of Xaml know-how.   All of this code could have been expressed using Xaml.  Conclusion: Knowing a little about Xaml can reek havoc on a well-structured Prism project.

The hallmark of these decisions is code complexity, your first clue things have gone astray.

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.  It was a prime example of the power and importance of design patterns in maintaining good form and structure.

Sunday, 27 December 2009

Prism Sample: Resources

An area of Prism development that often gets overlooked is the management of resources.  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.

Similar to modules, resource assemblies can have an accompanying interface assembly.  This is done by defining ComponentResourceKeys in your interface assembly and using them as resource keys in your resource dictionary and in your Views.

public static class Styles
{
    public static ComponentResourceKey LargeTextStyleKey
    {
        get { return new ComponentResourceKey(typeof (Styles), "LargeTextStyle"); }
     }
}

and in your Xaml...

<textblock text="My Sample TextBlock Style"
           Style="{StaticResource {ComponentResourceKey TypeInTargetAssembly={x:Type Interfaces:Styles}, ResourceId=LargeTextStyleKey}}" />

Taking this approach decouples your modules from the resource assembly.  The advantage to do this is not so much in the area of reuse, but more in the implementation of themes.  Any Views that require the use of a resource can simply refer to it by its ComponentResourceKey.

Additionally, I would only have the Shell load the external resources, since the View modules are now unaware of the external resource.  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.

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}).  This does not require the use of ComponentResourceKeys.

The area of theming WPF applications is a common one and there are a number of resources on CodePlex which address this area.  One example is the Razre WPF Framework, or you can build your own ThemeManager.

Conclusion
I think this pretty much concludes the PrismSample articles.  This was meant as an introduction for developers starting out with Prism and to provide some guidelines in setting up a Prism solution.  I hope this was of some use.  I'm certain others will have differing opinions, and that's okay too.  I'm always on the hunt for new approaches and new ideas.

I think Prism has a real future in WPF development.  Once you get into it and see the benefits, it changes how you think about and view WPF development; afterwards it is difficult not to think and develop that way, which is a good thing.

As always, comments/feedback welcome...

Thursday, 17 December 2009

Prism Sample: Basic Concepts

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.
One of the most basic aspects of code organisation is knowing “what goes where”.  This is especially true with Prism projects.  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.
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.  I’m always looking for ways to remove a dependency or decouple.  Even if I don’t have an immediate requirement to do that, as a general rule it’s a good idea.

Namespaces
Picking the right naming convention for your projects and namespaces is pretty important.  I would spend ample time on this before embarking on any serious coding.  Maybe start with a prototype solution and put in some basic modules, a shell, some services, and their accompanying interfaces.  Play around with it and massage it into something you're comfortable with.  I think there is a natural order and organisation for these various projects and components.

Microsoft's recommended namespace convention is:
Company.(Product|Technology)[.Feature][.Subnamespace]

for example, if I were creating an advertising module for Blogger, I would see something like...

Blogger.Advertising.Interfaces
Blogger.Advertising.Views
Blogger.Advertising.ViewModels
Blogger.Advertising.Services
Blogger.Advertising.Services.Interfaces

Microsoft has an excellent guideline for create .Net components at: http://msdn.microsoft.com/en-us/library/ms229026.aspx

Implementation vs Interface
It's important to understand the difference between implementation and interface as it applies to modular development.  An interface is simply a public contract that defines an exposed surface.  Whereas, implementation deals with the deploy or realisation of the interface.  Interfaces do not contain business logic,  simply a definition of what something will look like once it is implemented.
Prism and Unity makes heavy use of interfaces.  Interfaces are mapped to your implementation classes, either in code or in a configuration file.

The following tips may be obvious to some, but I felt it was worth mentioning:

Tip #1 - Do not create strong references to implementation assemblies.
The exception to this are assemblies which comprise your Model.

Tip #2 - Do not place anything in your implementation assemblies which forces other assemblies to create a strong reference.
An example of this are Event classes.  You may have a module which publishes events, presumably to be subscribed to by other modules.  Do not include the Event class in your module assembly, instead place it in your module's interface assembly.  This makes it available to other assemblies though the interface reference.  Another common example are enumerations.

Tip #3 - Do not register your implementation classes in the Module Initialize method.
Registering classes in the Initialize method implies a specific implementation, but not all implementations.  Instead map your classes in a Unity configuration file.

Tip #4 - Do not inject views into regions in the Module Initialize method.
I never understood why anyone would want to do this, as it pretty much ruins any chance of reusing the module.  Instead, delegate view orchestration to another module, layer or layout manager.

In fact, I can't think of good reason to put any code in the Module Initialize method.

These tips address some hidden or covert implementation that commonly occurs in Prism development.

Wednesday, 16 December 2009

Prism Sample: Introduction

I had a request to post some sample code illustrating the use of Model-View-ViewModel pattern, Controllers and DelegateCommands.  This lead to the creation of a sample Prism solution.  An interesting exercise, since it gave me a chance to incorporate many of what I consider to be Prism best practices.
I consider proper solution setup and organisation to be critical in working with Prism.  Mistakes made in this area often come back to haunt you.  There are many ways to organise your projects and code.  What is probably more important is pick a solution structure that everyone can agree with and stick with it.  A lack of agreement or ignorance of architecture can make team development a nightmare.

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.
You can download the solution here (408kb).  You will require Visual Studio 2008 SP1.  I've stripped out all XML documentation and PDBs to keep the file size down.

Please let me know if you run into any problems loading and running this solution.

Wednesday, 7 October 2009

Using OnValidate method in LINQ to SQL

If you are using LINQ to SQL you may have noticed the OnValidate partial method.

public partial class Person : INotifyPropertyChanging,
                  INotifyPropertyChanged
{
     ...
     partial void OnValidate(ChangeAction action);
     ...
}

This method gets automatically called when the class participates in the DataContext SubmitChanges.

When working with LINQ to SQL classes I prefer to keep my code generated classes separated from any modifications or customisations.  Normally, I will create a folder in my project called ExtendedClasses, there I can extend my business objects, giving them a <classname>.extended.cs file name.  This allows me to regenerate my business objects without fear of losing these customisations.

So, in my extended class file I will include...

partial void OnValidate(ChangeAction action)
{
    if (action == ChangeAction.Insert)
    {
        //Do validation for inserts
    }
   
    if (action==ChangeAction.Insert ||
        action==ChangeAction.Update)
    {
        //Do basic validation for inserts and updates
    }
}

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.  Any validation errors get raised by throwing an exception.
Because the OnValidate method is private, you may want to include a public Validate method.

public void Validate()
{
    if (PersonId==Guid.Empty)
    {
        OnValidate(ChangeAction.Insert);
    }
    else
    {
        OnValidate(ChangeAction.Update);
    }
}

With the public Validate method I can validate my business object from the UI layer before passing it down to my services layer.

try
{
    person.Validate();
}
catch (Exception e)
{
    MessageBox.Show(e.Message + "\n\n" + e.StackTrace);
    return;
}

Tuesday, 15 September 2009

UK Post Code Search using LINQ to XML

I recently delved into working with UK Post Codes, including validation and searching.  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.

This time, I was looking for something a bit more portable, like XML.

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.

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.  All of the search and validation routines utilise LINQ to XML to query the XDocument.

The class library relies on a PostCodes.xml file (supplied in the Test Harness project), which gets loaded as an XDocument.  I've included a small WPF Test Harness application which illustrates how this library is used.


To run this solution you will need Visual Studio 2008 SP1.  The source code is available here.

For those interested in this area, there is an informative government page on Postal Geography, which explains the structure of the UK post codes.  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.

Another site with useful information is: http://www.easypeasy.com/guides/article.php?article=64

Tuesday, 8 September 2009

IsIn Extension Method

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:
public enum StatusValues
{
 Open,
 Closed,
 Pending,
 Cancelled,
 Expired,
 Suspended
}

   ...

if(myObject.Status == StatusValues.Closed ||
   myObject.Status == StatusValues.Pending ||
   myObject.Status == StatusValues.Expired)
{  
   ...
}

This can become cumbersome when testing for a number of values.

The IsIn Extension Method simplifies this by taking a param list of values.
public static bool IsIn<T>(this T thisObject, params T[] values)
{
    if (thisObject != null && values != null && values.Length > 0)
    {
        foreach (var value in values)
        {
            if (thisObject.Equals(value))
            {
                return true;
            }
        }
    }

    return false;
}
Using this method, the above code can be rewritten as follows:

//using the IsIn Extension Method
if(myObject.Status.IsIn(StatusValues.Closed,
                        StatusValues.Pending,
                        StatusValues.Expired))
{
   ...
}

Monday, 31 August 2009

Retro Flip Clock WPF Control

I know, I know...I last thing we need is another WPF Clock.  However, I recently went looking for a Flip Clock control and found surprisingly few - in fact, no usable ones.  So, it was back to the drawing board.

Most of the attention has been on appearance, rather than functionality.  Feel free to modify and enhance.
You can download the source code with sample project here.

Sorry for the broken link, the server that hosted this file has been rebuilt and no longer contains my downloads.  Here is a link on my SkyDrive.  This zip file contains the core files, you will need to add them to a project.

Tuesday, 25 August 2009

Layout Manager for Prism v2

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.

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.

One common approach I would not recommend is injecting your views in your module's Initialize method.
public void Initialize()
{
    var view = new MyView();
    _Container.RegisterInstance<IMyView>(view);
    _RegionManager.Regions[RegionNames.Shell].Add(view);
}
This violates the encapsulation of the module, restricting the reuse of the module.

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.

Still this solution felt a bit too purpose-built. And other issues quickly arose, such as multiple layout support.  Ideally we were looking for a complete decoupling of regions and views with the ability to dynamically load layouts as required.

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.

To compile and run the LayoutManager you will need Visual Studio 2008 SP1 and the latest version of the Composite Application Guidance for WPF and Silverlight - February 2009.

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.

The LayoutManager maintains a collection of Layout objects, which define layout controls, along with the views that will reside in the layout.

Configuration
The LayoutManager is configured by a LayoutProvider specified in your app.config file.

<section name="layoutProvider" type="Composite.Layout.Configuration.LayoutProviderSection, Composite.Layout"/>

Currently, two providers are available: ConfigLayoutProvider and XamlLayoutProvider. Custom providers can be used by inheriting from LayoutProviderBase.

ConfigLayoutProvider
Defines the LayoutManager in the app.config file as shown below:
<layoutProvider name="ConfigLayoutProvider" type="Composite.Layout.Configuration.ConfigLayoutProvider, Composite.Layout">
    <layoutManager shellName="Shell" >
      <layouts>
        <layout name="FirstLayout" 
              filename="Layouts\FirstLayout.xaml" 
              fullname="First Layout" 
              isDefault="True"
              description="This is the default layout" 
              thumbnailSource="pack://application:,,,/LayoutManager.Infrastructure;component/Resources/Images/layout1.png">
          <views>
            <view typeName="LayoutManager.Infrastructure.IViewA, LayoutManager.Infrastructure" regionName="Left"  />
            <view typeName="LayoutManager.Infrastructure.IViewB, LayoutManager.Infrastructure" regionName="Right" />
            <viewModel typeName="LayoutManager.Infrastructure.IMenuViewModel, LayoutManager.Infrastructure" regionName="Menu"  viewProperty="View"/>
          </views>
        </layout>
        ...
          </layouts>
    </layoutManager>
</layoutProvider>

XamlLayoutProvider
Defines the LayoutManager in Xaml

<layoutProvider name="XamlLayoutProvider"
type="Composite.Layout.Configuration.XamlLayoutProvider, Composite.Layout"
filename="Layouts\LayoutConfiguration.xaml"/>

The source of the Xaml can be specified by type or by filename.
<Layout:LayoutManager xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                      xmlns:Layout="clr-namespace:Composite.Layout;assembly=Composite.Layout"
                      xmlns:Infrastructure="clr-namespace:LayoutManager.Infrastructure;assembly=LayoutManager.Infrastructure"
                      ShellName="Shell">
    <Layout:LayoutManager.Layouts>
        <Layout:Layout x:Name="FirstLayout"
                       Fullname="First Layout"
                       Filename="Layouts\FirstLayout.xaml"
                       Description="This is the default layout"
                       ThumbnailSource="pack://application:,,,/LayoutManager.Infrastructure;component/Resources/Images/layout1.png"
                       IsDefault="True">
            <Layout:Layout.Views>
                <Layout:ViewModel RegionName="Menu"
                                  Type="{x:Type Infrastructure:IMenuViewModel}"
                                  ViewProperty="View" />
                <Layout:View RegionName="Left"
                             Type="{x:Type Infrastructure:IViewA}" />
                <Layout:View RegionName="Right"
                             Type="{x:Type Infrastructure:IViewB}" />
            </Layout:Layout.Views>
        </Layout:Layout>
 ...
    </Layout:LayoutManager.Layouts>
</Layout:LayoutManager>

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.

The LayoutManager is loaded after all of the modules have initialized. In the Bootstrapper.cs:

protected override void InitializeModules()
{
     base.InitializeModules();
     InitializeLayoutManager();
}

private void InitializeLayoutManager()
{
     var layoutManager = LayoutConfigurationManager.LayoutManager;
     layoutManager.Initialize(Container);
     Container.RegisterInstance(layoutManager, new ContainerControlledLifetimeManager());
     //parameterless LoadLayout loads the default Layout into the Shell
     layoutManager.LoadLayout();
}
The LayoutManager requires use of the Container. Once your layouts have been loaded, call the Initialize method passing in the container.

Once that is done, you can register the LayoutManager in the container making it accessible to other modules.

Loading a Layout
Layouts are loaded by calling the LoadLayout method of the LayoutManager.

LoadLayout() loads the default layout in the Shell

LoadLayout(string layoutName) loads the named layout in the Shell

The MenuViewModel.cs illustrates the use of LoadLayout:
private void LayoutCommandExecute(ILayout layout)
{
var layoutManager = _Container.Resolve<ILayoutManager>(); 
layoutManager.LoadLayout(layout.Name);
}

The basic sequence of loading a layout is:
  1. If there is a current layout, remove it from the RegionManager.
  2. 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.
  3. Add the new Layout Control to the RegionManager.
  4. Register any Regions contained within the Layout Control.
  5. Load any views associated with the new layout.
Events
There are several events raised by the LayoutManager:

  • LayoutManagerInitializedEvent raised at the end of Initialize (see MenuViewModel.cs for an example of subscribing to this event)
  • LayoutLoadingEvent raised at the beginning of LoadLayout
  • LayoutLoadedEvent raised at the end of LoadLayout
  • LayoutUnloadingEvent raised before the current layout is about to be unloaded
  • LayoutUnloadedEvent raised after the current layout has been unloaded
All of these events are published through the EventAggregator.

Limitations
Currently there are several limitations with the LayoutManager, these are:
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.

Other Considerations
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.

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.

I have not tested the LayoutManager in all possible scenarios, such as nested layouts and custom RegionAdapters, or with Silverlight.

You can download the LayoutManager source code here.

Monday, 24 August 2009

StringBuilder Extensions

I recently had a requirement to modify some Html-based reports.  These reports were built up in code using a StringBuilder, along with report content data.  The plus-point is that it worked and delivered the desired reports.  On the downside, the code was tedious and verbose.  For example:
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("<TABLE id=\"Table2\" width=\"100%\">");
stringBuilder.Append("<TR style=\"page-break-inside : avoid\"><TD class=\"reportHeaderTitle\" >" + ResourceManager.GetString("ReportTitle", culture) + "</TD></TR>");
stringBuilder.Append("<TR><TD style=\"PADDING-LEFT: 5px; PADDING-BOTTOM:10px\" width=\"100%\">");
stringBuilder.Append("<TABLE id=\"Table2\" width=\"100%\">");
stringBuilder.Append("<TR style=\"page-break-inside : avoid\"><TD class='reportHeader' align=\"center\" width=\"50%\">" + ResourceManager.GetString("ReportSubTitle", culture) + "</TD>");
stringBuilder.Append("<TD class='reportHeader' align=\"center\" width=\"50%\">" + ResourceManager.GetString("ReportResults", culture) + "</TD></TR>");
...

I was staring at 1000s of lines of code like this.  After a while it was all a blur.

My first impulse was to subclass the StringBuilder and build up some Html-specific methods.  Unfortunately, the StringBuilder class is sealed.   I also looked at the HtmlTextWriter class, a class primarily used when working with custom server controls.  But, this seemed overkill for the purpose.  I just needed a clean way to build-up an Html string in code.

I then turned to writing a set of Extensions Methods to provide this functionality.
#region Using Directives

using System.Text;

#endregion

namespace Common.Extensions
{
    public static class StringBuilderExtensions
    {
        public static void BeginTable(this StringBuilder stringBuilder)
        {
            stringBuilder.Append("<table>");
        }

        public static void EndTable(this StringBuilder stringBuilder)
        {
            stringBuilder.Append("</table>");
        }

        public static void BeginRow(this StringBuilder stringBuilder)
        {
            stringBuilder.Append("<tr>");
        }
        ...
    }
}

In refactoring the code I first pulled all of the inline styles out and into style classes.  Then I began migrating the existing code over to use the new extension methods.  The refactored code looks something like this:

var stringBuilder = new StringBuilder();
stringBuilder.HorizontalRule();
stringBuilder.BeginH2();
stringBuilder.Append(ResourceManager.GetString("ReportTitle", _Culture));
stringBuilder.EndH2();

stringBuilder.BeginTable();
stringBuilder.BeginTHead();
stringBuilder.BeginRow();
stringBuilder.BeginCell("reportHeader");
stringBuilder.Append(ResourceManager.GetString("ReportSubTitle", _Culture));
stringBuilder.EndCell();
stringBuilder.BeginCell();
stringBuilder.Append(ResourceManager.GetString("ReportResults", _Culture));
stringBuilder.EndCell();
stringBuilder.EndRow();
stringBuilder.EndTHead();
...
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.  I personally find this refactored code much easier to read and maintain.

You can download the StringBuilderExtensions.zip here.
I hope this may be of some use.

Extension Method Usage

If you are like me, once you have the Big Extension Method Realisation you tend to go overboard on their use.  This is eventually followed by the more practical Extension Method Usage Realisation.  This second realisation puts Extension Methods into perspective.

For example, you could quite easily create an extension method like this:
public static bool IsNull(this object thisObject)
{
return thisObject == null;
}
This method can replace
if(myObject==null)

with...

if(myObject.IsNull())

But is it worth it?  Is there anything wrong with myObject==null?  Of course not.  So why change it or replace it with an extension method.  It adds no new functionality, just a change of syntax.
Additionally, you will often collect your extension methods and place them in a common assembly.  Use of the above extension method creates an dependency on this assembly.  But what does it buy you?  I would argue, nothing.  So, lose it.
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. 
An example of this is checking if a collection contains any items, kind of like a cousin of String.IsNullOrEmpty.  For me, this is a prime candidate for an extension method, and should have been included in the IList interface (IMHO).

public static bool HasItems(this IList collection)
{
return collection != null && collection.Count > 0;
}
So we reduce
if(myCollection!=null && myCollection.Count>0)

to a clean and simple

if(myCollection.HasItems())

I know there is not a shortage of resources on the web regarding extension methods.  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.

CodeProject Articles

I have authored two CodeProject articles on WPF and Prism.

WPF Gadget Container Control
http://www.codeproject.com/KB/WPF/WPFGadget.aspx

Layout Manager for Prism v2
http://www.codeproject.com/KB/WPF/PrismLayoutManager.aspx

If you are interested in this area of .Net, check them out and let me know what you think.