A discussion about Rich Internet Applications, and user experience focusing on architecture, design patterns and methodologies.

Showing posts with label XAML. Show all posts
Showing posts with label XAML. Show all posts

Monday, April 19, 2010

ViewModel and Design-Time Data

I have been mulling over different approaches for implementing the ViewModel (MVVM) pattern and feel that I’m close to a solution that I’m happy with.  I have the following criteria:

  • View First.  I don’t like the idea of the ViewModel having even the slightest dependency on the view.  That way I can easily isolate it and test it.  The view I have no intention of (unit) testing as it will not have any code.
  • MEF only.  For now, I’m focusing on lean and simple.  I was a big fan of Prism, but I’m shying away from big, frameworks that force me down a path.  I’m liking light-weight utility libraries better.  Sure I have to write more code, but I have full control and much more flexibility to adapt the solution to the requirements.
  • Blendable design data.  The first thing that excited me about WPF/e (original Silverlight code name) was the improvement in Designer/Developer work flow.  Giving the designer a better experience and more control over the interface design is definitely an advantage.

I originally thought it would be nice to have the ViewModel discoverable at design time (as discussed in this article by John Papa, but I had trouble getting the ViewModel to be registered by MEF at design time.  I then explored the new ViewModel support in Expression Blend, and I liked it.

In my experience the Designer typically creates the prototypes, hands them off to the developer and then needs to go back to update the design.  This has always been a painful process, especially in an ASP.Net web forms application. 

  1. The prototypes come as a Visio file, or html web pages. 
  2. The developer needs to spend a lot of time transforming this into an ASP.Net web page, and falls short of recreating the exact design. 
  3. The designer then has a really hard time working with the ASP.Net source and updates the original prototype. 
  4. The Developer needs to update the application page to match the new prototypes

The result is friction between the two teams, and a lot of UI bugs generated by QA.  Ideally, the developer and designer work should with the same files and do not conflict with each.  In the world of Silverlight 4, the following is possible:

  • The designer creates the interface in Expression Blend and attaches sample data to the forms
  • The developer adds functionality to the forms and Visual Studio, only modifying the bindings in the presentation layer
  • The designer can continue to make modifications to the presentation layer in Expression Blend even after the developer has worked with it

One of the challenges I faced working with MEF was troubleshooting import failures.  I managed to resolve all except the timing for import of the composition container itself in the base view.  I use this to resolve a viewmodel by name:

public static class ExportProviderExtensions

    {
        public static object GetExport(this ExportProvider provider, string typeName)
        {
            return GetExport(provider, typeName, typeName);

}

}

 



And then use this in the base View class:



    public class View : Page 
    {
        private string _viewModelName;
        public string ViewModelName
        {
            get { return _viewModelName; }
            set
            {
                _viewModelName = value;
                ViewModel = ContainerLocator.Container.GetExport(ViewModelName) as ViewModelBase;
            }
        }
        public ViewModelBase ViewModel
        {
            get { return (ViewModelBase)DataContext; }
            set { DataContext = value; }
        }
    }


The ContainerLocator just stores the CompositionContainer in a static property.



The sample view model simply creates some data:



    [Export]
    public class MainViewModel : ViewModelBase
    {
        public Collection<Thing> List { get; set; }
        public MainViewModel()
        {
            List = new Collection<Thing>()
                       {new Thing {Value = "One"}, new Thing {Value = "Two"}, new Thing {Value = "Three"}};
            RaisePropertyChanged("List");
        }
    }


The view model name is set in the view xaml:



<rf:View x:Class="Silverlight4.Composite.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:rf="clr-namespace:Refract.Views;assembly=Refract"  
    ViewModelName="Silverlight4.Composite.MainViewModel">


I could not get this to work in the designer, because the designer host did not properly register exported types in the assembly, but I realized that it is not necessary.  I can use Expression Blend to create a data source from a class.  Point the wizard to the view model and voilĂ , design time data that is customizable by the designer:



image



<Silverlight4_Composite:MainViewModel 
        Data="Aliquam cras duis integer" IsInDesignMode="True" >    
        <Silverlight4_Composite:MainViewModel.List>
                <Silverlight4_Composite:Thing Value="Curabitur maecenas phasellus class aenean"/>
                <Silverlight4_Composite:Thing Value="Praesent nunc curae nam"/>
                <Silverlight4_Composite:Thing Value="Quisque vivamus accumsan"/>    
        </Silverlight4_Composite:MainViewModel.List>
</Silverlight4_Composite:MainViewModel> 


Blend sets the data context on the first control you bind to, but I moved it to the root of the xaml:



<rf:View …
    d:DataContext="{d:DesignData /SampleData/MainViewModelSampleData.xaml}" …



The result (In Blend):



image



… and in the browser:



image

Saturday, April 17, 2010

Dictionarys in XAML

Short and simple post about how to declare and bind to a custom dictionary in Silverlight 4.  I had trouble finding a solid example of this since it has been properly introduced in the full release of Silverlight this past week.

Essentially I derived from Dictionary<String,String> and called it CustomDictionary within the application project.  Add a namespace declaration called local for the project and then:

<UserControl.Resources>
<local:CustomDictionary x:Name="dictionary">
<
sys:String x:Key="One">1</sys:String>
<
sys:String x:Key="Two">2</sys:String>
<
sys:String x:Key="Three">3</sys:String>
</
local:CustomDictionary >
</
UserControl.Resources>

<
Grid>
<
TextBlock Text="{Binding Source={StaticResource dictionary}, Path=[One]}"></TextBlock>
</Grid>



Quite simple really.  You bind to the dictionary resource and specify the key as the path.



Why do this?  I really like the idea of creating a dynamic and blendable ViewModel locator (thanks John Papa http://bit.ly/b11pUB) and I wanted to try my hand at doing this myself without the converter.



I’m planning on posting a blog on using MEF for composition and DI soon.  I think for smaller projects, it makes sense to keep it simple.  For larger projects, Unity might make more sense.

Wednesday, August 6, 2008

Silverlight LOB Architecture Design

<- User Experience for Line of Business    

A Silverlight application by its nature is a distributed app with a front-end on the client and a web service to provide connectivity to the data store.

image
Application Diagram

In order to decouple dependencies between components, I use dependency injection.  All components consumed by other components define a strong contract through an interface, making them replaceable and making unit testing simpler.  Since the front-end connection with the business logic is handled declaratively, no contract is required. 

Sample Application

For our working example, we have a straightforward requirement:

  • Display a list of users
  • Allow adding, updating and deletion of users

So we are defining a simple CRUD operation on an entity.  The following class diagram describes the different components needed to implement this using the Model-View-ViewModel design pattern.

 

image
Class Diagram

The view binds to the data model for interaction with the entities.  To handle user interaction, we will be binding to a component called "ViewModelAction" which encapsulates event handling and availability, similar to WPF commands.  The components are relatively lightweight and are focused on streamlining the binding process.  This allows the view contain absolutely no code.

The common functionality for these components is defined in a central library that could be re-used for other applications.  The View, Model, ViewModel and ViewModelAction base classes are all derived from a abstract class called Component which mainly implements property change notification through the INotifyPropertyChanged interface. 

Gotcha

One of the obstacles I ran into with declarative binding is that the visual designer attempt to instantiate all objects.  In the case of the model, this was bad as Visual Studio was attempting to connect to the web service and failing.  I added an "IsDesignMode" flag to component to wrap calls to external resources in my components.  This is the same solution to a similar problem in ASP.Net.

Up Next

I'm going to take a top down approach to subsequent blogs to keep my non-developer audience interested longer.  I will show how the view is defined in XAML, followed by the ViewModel (with kung fu action) and lastly the Model. 

Wednesday, July 23, 2008

User Experience for Line of Business

Background

I have long considered HTML to be a hindrance to user experience in business applications. This old "language" was designed for simple hypertext informational pages but patched and bandaged to support the ever-growing expectations of corporate clients. I was very excited to hear of Microsoft's new Presentation Foundation and have been working toward promoting it as a replacement to HTML for intranet style projects.

Crossroads

After much research, my path is chosen. I have focused my initial research on Silverlight for its flexibility and cross-platform support, but I plan on including WPF in my long-term efforts. I have also chosen Model-View-ViewModel (MVVM) as the design pattern for its intuitive elegance with Silverlight's declarative model. WPF has better support for some of the MVVM's architecture, so I have taken a simplistic approach to some of the challenges in order to keep the implementation relatively light-weight.

I have been inspired and guided by tutorials and blogs that I have seen, so thanks to the online community for the invaluable information they provide. Thanks to all.

Model-View-ViewModel

It basically states that modern design patterns follow a simple philosophy:

  • Applications implement a model that represent the data store. This is the "Model".
  • The "View" renders the display and allows users to interact with data.
  • Business rules and application workflow are handled by the "ViewModel". This component provides endpoints for declaratively binding to data and actions.

More on this here.

There is also an article by Dr. WPF about Model-View-Poo that I enjoyed.

Practice Application

I chose to build an administration module for a web application as a goal to work towards. Basically, it would display a list of users and allow editing of a user in a detail screen.

The solution plan would be as follows:

ProjectDescription
AdminThe Silverlight app., implementing the Views and View Models
ClientLibraryFunctionality shared between Silverlight apps. including the Model
DataServiceA WCF service providing database operations to the client
WebThe web application hosting the Silverlight apps.
BaseCommon functionality for all MVVM style solutions

Next Up

For my next trick, I'd like to describe the Base and ClientLibrary projects in detail. The Web and DataService are not really relevant for UX discussion, so I will not be getting into them.

About Me

My photo
Toronto, ON, Canada
I am a technical architect at Navantis, with over 12 years experience in IT. I have been involved in various projects, including a Hospital information system called CCIS for which my team received the 2007 Tech-Net innovation award. I have been working with Silverlight since beta 1, and am very keen on practically applying this technology and WPF to line of business applications.