Pragmatic Choices: Bye Bye Silverlight

Posted by Dave Bouwman | Posted in ASP.NET MVC, M-V-VM, Silverlight | Posted on 09-07-2009

2

Just in time for the release of Silverlight 3, I’m bidding farewell to Silverlight on my current project.

bye-silverlight

I’ve been working with Silverlight for about a month, and despite my best efforts it became clear that my project was just not going to come together the way I’d hoped. Thus I pulled the plug on Silverlight, and switched back to ASP.NET MVC and Dojo. Interestingly, I was able to re-build all the existing functionality in less than one day – things go fast when you’ve got a lot of experience with a technology!

I made this switch for a number of reasons, not the least of which was simple pragmatism – I was making relatively little progress with Silverlight, and the application did not really “require” Silverlight per-se.

I had chosen to to use Silverlight for a number of reasons:

1) The promise of ADO.NET Data Services (aka Astoria) to streamline the Data Access service layer

2) The promise of XAML Data Binding and/or DataForms to simplify client-side form management.

3) Prism’s promise of an easy to use, testable, application model with clean separation of concerns.

What I found is that while each of these features is really killer on it’s own, actually rolling all of them together is non-trivial. Learning all of these technologies while trying to build a large application (more than 50 data entry screens and lots of business logic) was just not viable. I’m sure if I had a team of 3 developers, and we had 6 months to get up to speed on XAML, ADO.NET Data Services / RIA Services, Prism, Commanding, XAML Data Binding, and Silverlight Unit Testing, then this application would merely be “challenging”. Since my team and I have built multiple similar apps using ASP.NET MVC and Dojo, there are significantly fewer “unknowns” as well as a ton of existing code we can leverage.

So, as I bow out, here are some thoughts about Silverlight…

Silverlight itself is pretty cool, but the tooling for Xaml at Silverlight 2 was harsh at best. The Xaml intellisense in Blend3 is a big improvement in the work flow. Designing the UI’s took a little getting used to because you don’t really have all the Windows or HTML form controls. Thus a fair bit of time was spent just getting up to speed with what was viable.

One I got a handle on what I could do in the UI, it was time to figure out how to build the application itself. Prism (Composite Application Guidance for WPF and Silverlight) is really cool, and there are a lot of intro level posts and videos out there. From what I can see, this is “the” way to build a “serious” Silverlight application. However, unless you’ve got a solid handle on Xaml, and DataBinding in WPF/Silverlight, it’s not easy to sort out how the View separation is supposed to work in non-trivial situations (i.e. taking commanding beyond simple buttons).

Additionally, there is lots of talk about Model-View-ViewModel as “the” design pattern to use, yet the Prism guidance does not show any examples of this (it focuses on Supervising Controller and Presentation Model). The best resource I found for M-V-VM in Prism was David Hill’s Prism quick start kit and sample app. The sample app is still pretty simple, but it is M-V-VM, and you can follow what’s going on. If this was extended to show best practices integrating ADO.NET DataServices, creation of client side proxy classes implementing INotifyPropertyChanged (needed for Two-Way data binding), it would be an awesome resource. Along those lines I did come across some T4 templates that facilitate creating client side proxies that actually support Two-Way databinding (on a side note, the next release of Astoria will have updated client proxy generators which will include INotifyPropertyChanged)

Also the Prism Reference implementation mixes both of these patterns in different areas of the app, which makes it difficult to keep things straight. Not to pick on the reference app, but it also side-steps the issue of talking to “real” services by just stubbing the services out pulling from static, client-side data sources. It would be really good to have some example code that’s calling back to ADO.NET Data Services over, oh, I don’t know, let’s say Northwinds ;-)

Managing resources in Prism projects was also confusing. If you want Blend to see your resources (mainly images in my case) they need to be in the assembly containing the module. However, I could not sort out a clean way to then have those resources move over to the Shell assembly and thus make their way into the xap file. I ended up simply having copies of all my images in both my module assemblies and the shell assembly. Not ideal, and I’m sure there is a good way to handle this, but it was the least of my concerns.

Another thing I struggled with was that my UI was going to be pretty complex – the final app will have over 50 screens. The UI Composite capabilities of Prism would be nice to use, but given that we are an Agile shop, we don’t do big design up front. But, the regions need to be defined in the Shell at the beginning of the development cycle. I sense some problems down the road with this. Additionally, in order to decompose the Views and ViewModels into convenient pieces I would like to have different sets of regions in the app. I’m sure that the patterns & practices guys could work a way to make that happen, but it sure was not clear to me how to whip that up.

Summary

Overall, it was an interesting journey, and I’m planning on building a much simpler resource planner application using Silverlight in my spare time. I intend use Prism on it, and give that it’s much smaller (4 screens) I think it will be a better starting point.

On a side note for the GIS people reading this, I never really got to the point of using the ESRI Silverlight control in this project. The few demo apps I’ve built with this control would indicate that it will be just as easy to use as any other Silverlight control.

Silverlight DataGrid Current Item as Click.CommandParameter

Posted by Dave Bouwman | Posted in M-V-VM, Prism 2, Silverlight | Posted on 02-07-2009

0

Note: This applies to Prism v2 with Silverlight 3 Beta.

So I’ve added a button into a column of my DataGrid, and I want to bind in the Click handler to my ViewModel, as well as pass the selected item into said handler.

I’m not going to go into the details of Commanding in Prism at this time (maybe later), but here’s what the xaml looks like:

...
<data:DataGridTemplateColumn Header="Details">
    <data:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button Commands:Click.Command="{Binding Path=Value, Source={StaticResource ViewDetailsCommand}}"
                    Commands:Click.CommandParameter="{Binding}"
                    Cursor="Hand"
                    Content="Details" />
        </DataTemplate>
    </data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
...

The Click.Command is a little out of the ordinary in that the Binding Path is set to Value, and the Source is a StaticResource on the control. There are a few hoops to jump through on this, but the Prism reference implementation application (RIStockTrader) does show how this works.

What had me scratching my head was how to send in the object which represents the current row in the grid. All of the examples looked like this:

Commands:Click.CommandParameter="{Binding Path=ItemId}"

Which is great when you just want to send the Id of the item in. But in my case, I want the actual object so I can send that to the "Details" form for editing. In hind sight it’s obvious that you would set the CommandParameter to the "Binding", since that’s the item itself, but it was one of those things that you don’t think would make sense.

Anyhow – through the power of Google, I hope this saves someone else some time/frustration.

Silverlight Templating: Bending Controls to Your Will

Posted by Dave Bouwman | Posted in Sample Code, Silverlight | Posted on 22-06-2009

0

I’m building an forms-over-data application that needs to control edit access based on the user’s role, and the active item’s workflow status.

Download Sample Code

When building similar functionality in ASP.NET MVC applications, we’ve handled this scenario by having the server render a partial page, and based on the user’s edit access, we emit form elements (text areas, select boxes etc), or just content. The partial is injected into a containing DIV element, and all is well.

Of course, this is not an option with Silverlight – well I guess we could build separate read-only and read-write Views, but that would be a bunch more work. Why not leverage the IsEnabled property instead – that should work, and it’s ok from a sematic point of view (purists may want to sub-class all the controls and add a "IsReadOnly" property and use that, but I’m a pragmatist – IsEnabled is a reasonable compromise).

The only problem is that by default the control’s content is grayed out when it is disabled (shown below). This makes the "Read Only" state less than "readable"…

sl-disabled

With WinForms, we’d just be out of luck. But since this is XAML, we can override the control’s template and change it’s look and feel for the various states.

Since we’ll want these styles accessible across our entire application, we’ll be adding the templates into App.xaml. But before we do that we’ll need to add a namespace for the visual state manager (vsm)

 

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Class="sl_templating.App"
             xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
             >

 

From there, we grab the default template from MSDN ( http://msdn.microsoft.com/en-us/library/dd334408(VS.95).aspx ) and assign it a key so we can force our combo box control to load it’s template from App.xaml instead of it’s dll.

<Style TargetType="ComboBox" x:Key="DTSComboBox">
...
</Style>

Then in our page (or to be more specific our Views) we tell the combobox to load it’s style from the static resource

<ComboBox x:Name="cboComboBox" IsEnabled="True" Grid.Row="0" Margin="5,5,5,5" 
       Style="{StaticResource DTSComboBox}">
       <ComboBoxItem Content="Thing One"/>
       <ComboBoxItem Content="Thing Two" IsSelected="True"/>
       <ComboBoxItem Content="Thing Three"/>
   </ComboBox>

 

Now it’s time to have fun – we change the template to match what we need. For the first cut here’s what I was looking for:

Combo Box: When disabled, gray out the drop down button, and the border, but leave the text readable

TextBox: Gray out the border, but leave the text readable.

Visual States

For this sort of thing, we are going to be modifying the visual states for the controls. The state we are interested in is called (not surprisingly) "Disabled". So we locate this in the Visual State Manager section of the control template…

<vsm:VisualState x:Name="Disabled">
    <Storyboard>
        <DoubleAnimation Storyboard.TargetName="DisabledVisualElement"
                         Storyboard.TargetProperty="Opacity" To=".7" Duration="0"/>
    </Storyboard>
</vsm:VisualState>

and we see that when the control’s state is changed to Disabled, a Storyboard with the name "DisabledVisualElement" is called. So we go and locate that…

<Border x:Name="DisabledVisualElement"
        Background="#A5F7F7F7"
        BorderBrush="#A5F7F7F7"
        BorderThickness="{TemplateBinding BorderThickness}"
        Opacity="0" IsHitTestVisible="False"/>

And from the looks of this, we can see that the Background and Border are set to a lovely gray (F7F7F7). Since we know that text content of a control is rendered in the Background color, we simply remove that property.

<Border x:Name="DisabledVisualElement"
        BorderBrush="#A5F7F7F7"
        BorderThickness="{TemplateBinding BorderThickness}"
        Opacity="0" IsHitTestVisible="False"/>

Voila! The disabled state for our TextBox will leave the text color as is, and just gray out the border, thus giving a visual cue that it’s read-only.

For the ComboBox, it’s a similar process, but complicated by the fact that the ComboBox is made up of multiple parts. We can leave the ToggleButton as is – it gray’s itself out nicely, and that’s fine with us. The other default behavior is to draw the control as a filled rectangle with a opacity set. This is what "grays" out the ComboBox item. Instead of setting a Fill, we just set the Stroke to a nice gray (the illustrious F7F7F7 again).

<Rectangle x:Name="DisabledVisualElement"
           RadiusX="3" RadiusY="3"
           Stroke="#A5F7F7F7" Opacity="0" IsHitTestVisible="false" />

That’s it. Now our controls enable & disable nicely, and the content is still readable.

sl-disabled-templatesd

This is clearly just scratching the surface of what you can do with templating, and I’m sure I’ll be digging into more controls like this, but it’s a nice capability to have.

Building Line-of-Business Apps with Silverlight 2.0: Part 1

Posted by Dave Bouwman | Posted in .NET, Silverlight | Posted on 10-06-2009

1

While I’ve been playing around with Silverlight for a while now, the time has come to build something a little bigger with it. Here’s the situation:

  • I’m Converting an Access/SQL Server application over to use a Silverlight 2.0 front end with ADO.NET Data Services on the back.
  • Database already exists, with 83 tables, including users and roles.
  • We need custom Authentication and Authorization services to control who can view/edit data
  • Application will have about ~30 User controls, which will be composed into about ~20 screens

Given this situation, I needed to find a framework that’s proven instead of trying to hack something up myself.

My goals were:

  • the client side Silverlight code needs to be unit testable
  • clean Separation of Concerns where ever possible – both to support unit testing and so we use "fakes" during development
  • Something that’s documented so myself and others on the team can figure it out.

After some Googling, it came down to two options:

Hand-Rolled Model-View-ViewModel (MVVM) or the Composite Application Library (aka Prism v2) from Microsoft Patterns and Practices.

Having used Enterprise Library, I knew that the MS Patterns and Practices stuff would be complex, but it would work. In an effort to keep things simple, I took a peek at "raw" MVVM first.

I’ll also mention that Nikhil Kothari has created Silverlight.FX – “light-weight application framework for building Rich Internet Applications with Silverlight 2”. While I have huge respect for Nikhil, and the project looks promising, it seemed a little too big to take on with just his blog posts and source code as documentation.

"Raw" MVVM in Silverlight 2.0

Conveniently there is a fair bit of information on MVVM floating around, so it was relatively easy to get the gist of things. One of the best resources was this screen cast by Erik Mork at Silver Bay Labs.

silverbay

Erik walks through the basics of the pattern by referencing an article by Shawn Wildermuth in MSDN Magazine, and then shows how to build out a very simple sample application based on the article’s code, and shows how to test the ViewModel using the Silverlight test harness.

As Erik notes here (he uses a media player that sync’s the code display with the video, and it’s bookmarkable!), the down-side of using "raw" MVVM in Silverlight is that you still need to have some "goop" in the code behind that fires events back into the ViewModel (due to the lack of "commanding" in vanilla Silverlight). Ideally we’d like to avoid the code-behind and have the ViewModel linked to the View (XAML) declaratively.

Another downside is that while MVVM provides a pattern for the individual views, it does not provide much infrastructure to create an application that’s composed of many views – I’d have to roll this myself or hack parts from a variety of samples – not idea. Conveniently though, we can use MVVM with Prism…

Composite Application Library aka Prism

Many people have heard of the “Old” Composite Application Block (aka “CAB”), and that alone could be enough to scare some people off. Although it shares a similar name, the Composite Application Library is much different. Prism is a set of components, services and patterns that can help with the construction of  MVVM Silverlight applications. It includes:

  • The Microsoft Unit Inversion of Control Container
  • Commanding for Silverlight (declaratively linking the ViewModel to the View in XAML)
  • Centralized Event Aggregation (makes loosely coupled designs much easier)
  • Support for UI composition from multiple views

Getting Started with Prism

As like most other things from Microsoft Patterns and Practices, this stuff is both complex and well documented. In fact, the Guidance is simply amazing. It has overviews of all the key components, solid descriptions of how/when to use them, as well as “Quick Start” project that show the concept in action. They also have a “reference implementation” which seems to combine all possible aspects and combinations in one project. I’d hold off on looking at this until you’ve got a good handle on the individual components though, as it’s pretty hairy.

But to get a good idea of how Prism works, there are some good videos I recommend checking out:

Erik Mork of SilverBayLabs.org has a couple of great really simple intro videos. These were great for introducing the basic components – the shell, models, viewmodels and how they relate.

Channel9.com has a 4 part series with Bob Brumfield and Erwin van der Valk from patterns and practices showing to build a modular application using Prism.

At this point I’ve managed to get my app’s structure laid out, I’ve got login capabilities which correctly add cookies which allow access to secured services, and I’ve got a few rough modules and a rough means to transition between them. Learning Silveright, XAML, Expression Blend, MVVM, Unity, and Prism all at once made for a pretty harsh learning curve, but I’m past the roughest parts. In some cases I’ve departed from MVVM due to some limitations on databinding (twoway data binding to a PasswordBox is apparently verboten), and I have a little “goop” in my View code-behinds, but I think these are corner cases, and the “main” modules (the ones with the business logic) should be MVVM.

When I get some time, I plan on posting some notes and sample code for things which were difficult to understand, or implement.

ASP.NET MVC + Dojo vs. ADO.NET Data Services + Silverlight

Posted by Dave Bouwman | Posted in Dojo, Javascript, Silverlight | Posted on 08-04-2009

4

I’ve been doing some research comparing the use of ASP.NET MVC + Dojo and ADO.NET Data Services (aka Astoria) + Silverlight for Rich Internet Applications, and thought I’d share my findings and conclusions.

Context

Before diving in, I should mention that the context for this comparison is line-of-business, forms-over-data applications. Mapping is an element of the application, but we are not talking about map-centric applications (I may do another post on that later). The application that I’m specifically looking at has more than 40 screens of forms, backing into a data model with more than 100 tables.

ASP.NET MVC + Dojo

The client side library could just as easily be ExtJS, or any other javascript based UI toolset. That said, here’s a screen cap of the sort of site I’m talking about.

rai2

The flow is Search in the upper left, results listed below that, and details on the right. The details for a Project are broken out onto 6 tabs, including a map.

ria3

In this case, we are using the ESRI Javascript API – which is convenient because we are already loading Dojo, so adding this map into the mix does not require an additional javascript framework.

Service Model Design

In order to drive this UI, we have a lot of moving parts behind the scenes.

In front of the database we have a data access layer, which is generated using SubSonic. We front that with an interfaced based Repository, which exposes a set of domain objects. These domain objects are consumed by ASP.NET MVC Controllers, which in-turn create either JSON responses, Views, or Partial Views depending on the scenario. Once in the browser, Dojo takes over orchestration. Where convenient, we just send JSON data to the UI, but in other cases it’s simply more efficient to create the HTML on the server, and ship that across as a partial view which is then parsed by Dojo after being inserted into the DOM. The following image shows how all these come together.

ASP.NET MVC + Dojo Service Model

(click to view larger version)

The key thing here is that the vast majority of this system is hand coded. This allows complete control, but it takes a lot of work – even once we’ve got good patterns setup. Another downside is that even with the cross browser support built into Dojo, there are still small oddities which take a lot of time to track down.

We are more than half way through this application, so I doubt we’d change at this point, but since we have everything in place, it seemed like a good candidate to do a comparison to…

ADO.NET Data Services + Silverlight

The quick story on ADO.NET Data Services (besides having a really lame name ) is that it can very easily provide a REST layer on top of your data access layer. This is done via a WCF service, and as long as your data access layer supports IQueryable<> and IUpdateable<> you can configure the service to use your DAL. MSDN Magazine has a good article that covers the basics of ADO.NET Data Services.

While we have a data access layer in the application, it’s not setup for IQueryable or IUpdatable. So the other option is to use the Entity Framework. While the Entity Framework has taken a lot of grief, it seemed like a reasonable option to try since it’s baked in, relatively easy to configure, and purports to do what I need.

Since this is pretty new stuff, I’ll go through the basic steps here. For more detailed information, check out the Data Driven Services with Silverlight 2 book.

So, in Visual Studio, I simply add a new Entity Data Model to my ASP.NET MVC application (which I’m using to host the Silverlight app)

image

And then connected it to my database, and selected some tables I wanted to work with. This created the Model as shown below…

image

After that, I added an ADO.NET Data Service to the project…

image

Bound it to the Entity Framework model (ProjectEntities) and set some data access rules in the service.

image

Build, and shazam! My model is exposed as REST resources. By default queries return ATOM format, but by changing the accept header on the request, you can get JSON back.

image

On the Silverlight side of things, there is a little more work to do, but essentially we include the Data Services client side library, make a reference to the service which creates the proxies, extend the proxy classes to support INotifyPropertyChanged, and then setup bi-directional data binding. (See the MSDN article referenced above for more details)

Which makes the Service Model looks like this…

Service Model

This is a much simpler model, and much of the dirty work can be done via configuration vs. coding.

Conclusions

In my mind, the ability to rapidly configure a database for access via REST, and at the same time setup a browser agnostic, rich user interface with data binding sets the Silverlight + ADO.NET Data Services far ahead of the more traditional ASP.NET MVC + Dojo model, and I’ve your team already has .NET chops, this is just an extension of the existing skills. Additionally, I think that Silverlight 3 will up the ante again, with more controls, and even better tooling to streamline this development process.

That said, for the particular application was looking at, we are sticking with ASP.NET MVC + Dojo for two reasons: 1) the database “sub optimal” so we’d have a LOT of work making it play nice with the Entity Framework, and 2) we are about half done, and the client wants a consistent look/feel across the entire application. Switching to Silverlight would require re-doing what we already have, and while I think development would be faster, it would be able to make up the difference. We will seriously look at Silverlight + ADO.NET Data Services for new line-of-business projects, including some upcoming product development.

ESRI Silverlight API: Defining Unique Value Renderer in XAML

Posted by Dave Bouwman | Posted in ArcGIS Server, Silverlight | Posted on 08-04-2009

2

I’ve been creating some proof of concept applications in Silverlight, and one thing I needed to do was apply a unique value renderer using PictureMarkerSymbols to some points on a FeatureLayer.

Initially I looked in the Samples and Reference sections of the ESRI Silverlight Resource Center. However, I was some what stymied. The Samples had a simple example of loading a feature layer, but it used the built-in clustering. I could find all sorts of details in the API Reference, but that does not help sort out how to setup a renderer in XAML.

Finally I stumbled into the Concepts section. I had figured that this section would be some very basic stuff – but there are a number of very useful code examples in there – specifically an example creating renderers in XAML. The example is for polygons, and is pretty comprehensive, but I thought I’d share a code sample for a unique value renderer using a PictureMarkerSymbol, as this is very much akin to slapping push-pins into other map canvasses like Google Maps or Virtual Earth.

The idea is pretty simple – in the Grid.Resources section of your XAML, define a bunch of PictureMarkerSymbols with names, then create a unique value renderer, and add in unique value items, which tie the attribute value to the specific marker symbol using data binding to the symbols we just defined. Follow that? It makes more sense in XAML…

<Grid.Resources>
    <esriSymbols:PictureMarkerSymbol x:Name="HelicopterSymbol" Height="40" Width="40" Source="Assets/images/i_helicopter.png" />
    <esriSymbols:PictureMarkerSymbol x:Name="DozerSymbol" Height="40" Width="40"  Source="Assets/images/i_truck.png" />
    <esriSymbols:PictureMarkerSymbol x:Name="PumperSymbol"  Height="40" Width="40" Source="Assets/images/i_firetruck.png"/>
    <esriSymbols:PictureMarkerSymbol x:Name="JumperSymbol"  Height="40" Width="40" Source="Assets/images/i_fireman.png"/>
    <esri:UniqueValueRenderer x:Name="FireResourcesRenderer" Attribute="Type" >
        <esri:UniqueValueRenderer.Infos>
            <esri:UniqueValueInfo Value="HELO" Symbol="{StaticResource HelicopterSymbol}" />
            <esri:UniqueValueInfo Value="DOZER" Symbol="{StaticResource DozerSymbol}" />
            <esri:UniqueValueInfo Value="PUMPER" Symbol="{StaticResource PumperSymbol}" />
            <esri:UniqueValueInfo Value="JUMPER" Symbol="{StaticResource JumperSymbol}" />
        </esri:UniqueValueRenderer.Infos>
    </esri:UniqueValueRenderer>
</Grid.Resources>

Then in the FeatureLayer definition we bind the renderer property to the renderer we defined in the Grid.Resources.

<esri:FeatureLayer
      
ID=”FireResources”
      
Url=”http://yourserver/ArcGIS/rest/services/yourmapeservice/MapServer/0″
      
Where=”1=1″
      
ClusterFeatures=”False”                     
      
Renderer=”{StaticResource FireResourcesRenderer}”>
    <
esri:FeatureLayer.OutFields>
        <
sys:String>Type</sys:String>                               
    </
esri:FeatureLayer.OutFields>
</esri:FeatureLayer>

And that’s it!