Silverlight – Image Resources Fail to Display in Popup unless Application RootVisual is a UserControl (or the Popup is added to the Visual Tree!)

Whilst developing a LOB application using Silverlight and Prism we came across the bug described in the title above.

To replicate, try adding this code to a new Silverlight Application:  (of course modifying the image uri to point to a valid source)

   1: public partial class MainPage : UserControl
   2: {
   3:    public MainPage()
   4:    {
   5:       InitializeComponent();
   6:       
   7:       var i = new Image
   8:       {
   9:          Source = new BitmapImage(
  10:             new Uri(@"/ImageProblem;component/Resources/Silverlight.png", UriKind.Relative))
  11:       };
  12:  
  13:       new Popup { Child = i, IsOpen = true };
  14:  
  15:    }
  16: }

… and modify Application_Startup in app.xaml.cs to this…

   1: private void Application_Startup(object sender, StartupEventArgs e)
   2: {
   3:   Grid g = new Grid();
   4:    g.Children.Add(new MainPage());
   5:    this.RootVisual = g;
   6: }

…then run the app.  You will notice the image does not show in the popup.  If you change the RootVisual back to ‘MainPage’ (a usercontrol) and re-run the app the image will show.  Alternatively you can add the popup to the visual tree to solve the problem.  I do agree the sample code above is contrived, but the code has been reduced (from something far more sensible) to its most fundamental parts to show the problem.

Hopefully this post may save someone else the hours of effort tracking down and working around this rather unusual bug.

Silverlight Commanding – Part 2

In my last post I talked about a commanding API that lended itself to custom routing, bubbling and centralized state change notification.  Whilst the techniques described in the last post are great for certain scenarios, I prefer to keep code in my views to a minimum and thought it would be best to blog about an example of commanding in Silverlight using the ever popular MVVM pattern.  The library and sample app can be found here.

Here’s a look at the sample app..

image

The concept is fairly simple, the view has elements that may be active or not depending on certain states that may be set by the user or other parts of the app.  The commanding implementations are fairly similar to DelegateCommand<object> from Prism, but allow the WPF style CommandManager.InvalidateRequerySuggested approach to managing command state.  Why is that important?  Well, in the example above, the buttons (on a toolbar for example) could be dynamically added, so it may not be that easy to know what commands to call DelegateCommand.RaiseCanExecuteChanged.

The View above is defined as follows with no code-behind.

   1: <UserControl x:Class="CommandingBlogSamples.RelayCommandDemoView"    
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:     xmlns:commands="clr-namespace:iMeta.Windows.Commands;assembly=iMeta.Windows"
   5:     xmlns:CommandingBlogSamples="clr-namespace:CommandingBlogSamples" 
   6:     Width="400">
   7:    <UserControl.DataContext>
   8:       <CommandingBlogSamples:RelayCommandDemoViewModel/>
   9:    </UserControl.DataContext>
  10:    
  11:    <Border BorderBrush="Black" BorderThickness="1">      
  12:       <StackPanel Background="DarkGray" >
  13:          <StackPanel Orientation="Horizontal">
  14:             <CheckBox Content="Enable A" Margin="10" IsChecked="{Binding IsAEnabled, Mode=TwoWay}"/>
  15:             <CheckBox Content="Enable B" Margin="10" IsChecked="{Binding IsBEnabled, Mode=TwoWay}"/>
  16:             <CheckBox Content="Enable C" Margin="10" IsChecked="{Binding IsCEnabled, Mode=TwoWay}"/>
  17:          </StackPanel>
  18:          <StackPanel Orientation="Horizontal" Background="LightGray">
  19:             <Button Content="A" Margin="10" commands:Click.Command="{Binding ACommand}"/>
  20:             <Button Content="B" Margin="10" commands:Click.Command="{Binding BCommand}"/>
  21:             <Button Content="C" Margin="10" commands:Click.Command="{Binding CCommand}"/>
  22:             <Button Content="AB" Margin="10" commands:Click.Command="{Binding ABCommand}"/>
  23:             <Button Content="AC" Margin="10" commands:Click.Command="{Binding ACCommand}"/>
  24:             <Button Content="BA" Margin="10" commands:Click.Command="{Binding BACommand}"/>
  25:             <Button Content="BC" Margin="10" commands:Click.Command="{Binding BCCommand}"/>
  26:             <Button Content="ABC" Margin="10" commands:Click.Command="{Binding ABCCommand}"/>
  27:          </StackPanel>
  28:          <Border BorderBrush="DarkGray" BorderThickness="0 1 0 0" Background="White">            
  29:                <TextBlock Margin="5 5 5 5" TextWrapping="Wrap"
  30:                   Text="As an example, the Buttons above may have been added dynamically, with the state on the view model being set by various parts of the application rather than the checkboxes above."/>            
  31:          </Border>
  32:       </StackPanel>
  33:    </Border>
  34: </UserControl>

Note the View has a DataContext set to our view model, looking something like this:

   1: public class RelayCommandDemoViewModel : INotifyPropertyChanged
   2: {
   3:    private bool _isAEnabled;
   4:    // other fields for B and C omitted for brevity
   5:  
   6:    private readonly RelayCommand<object> _aCommand;
   7:     // other commands omitted for brevity
   9:    public RelayCommandDemoViewModel()
  10:    {
  11:       _aCommand = new RelayCommand<object>(ExecuteA, CanExecuteA);
  12:    }
  13:  
  14:    public RelayCommand<object> ACommand
  15:    {
  16:       get { return _aCommand; }
  17:    }  
  18:  
  19:    public bool IsAEnabled
  20:    {
  21:       get 
  22:       {
  23:          return _isAEnabled; 
  24:       }
  25:       set 
  26:       {
  27:          if (value!=_isAEnabled)
  28:          {
  29:             _isAEnabled = value;
  30:             RaisePropertyChanged("IsAEnabled");
  31:          }
  32:       }
  33:    }  
  34:  
  35:    public event PropertyChangedEventHandler PropertyChanged;
  36:  
  37:    private void RaisePropertyChanged(string propertyName)
  38:    {
  39:       CommandManager.InvalidateRequerySuggested();
  40:       if (PropertyChanged != null)
  41:          PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  42:    }
  43:  
  44:    private bool CanExecuteA(object arg)
  45:    {
  46:       return _isAEnabled;
  47:    }
  48:    private void ExecuteA(object obj)
  49:    {
  50:       MessageBox.Show("A");
  51:    }     
  52: }

A notable point to mention is the call to CommandManager.InvalidateRequerySuggested – without this we would require something along the lines of:

   1: _aCommand.RaiseCanExecuteChanged();
   2: _abCommand.RaiseCanExecuteChanged();
   3: _abcCommand.RaiseCanExecuteChanged();
.. for each property change that can affect related commands.  This becomes more of a problem when it is not known what commands may be bound up or whether other commands residing in different components of the system may be affected by the state change. 

 

To supplement this post I have provided 2 examples of how the InvalidateRequerySuggested behaviour can be automated, removing the need to call it in the view model PropertyChanged handler.

Version 1: Similar to WPF, CanExecute is re-evaluated when typical user interaction occurs:

   1: public static class WpfCanExecuteOMatic
   2: {
   3:    private static UIElement _rootVisual;
   4:    private static readonly MouseButtonEventHandler _mouseActionHandler = RootVisualMouseAction;
   5:    private static readonly KeyEventHandler _keyActionHandler = RootVisualKeyAction;
   6:  
   7:    public static void AttachTo(UIElement rootVisual)
   8:    {
   9:       Detatch();
  10:       _rootVisual = rootVisual;
  11:       Attach();
  12:    }
  13:  
  14:    private static void Attach()
  15:    {
  16:       if(_rootVisual == null)
  17:          return;
  18:       _rootVisual.AddHandler(UIElement.MouseLeftButtonDownEvent, _mouseActionHandler, true);
  19:       _rootVisual.AddHandler(UIElement.MouseLeftButtonUpEvent, _mouseActionHandler, true);
  20:       _rootVisual.AddHandler(UIElement.KeyDownEvent, _keyActionHandler, true);
  21:       _rootVisual.AddHandler(UIElement.KeyUpEvent, _keyActionHandler, true);
  22:    }
  23:  
  24:    static void RootVisualKeyAction(object sender, KeyEventArgs e)
  25:    {
  26:       CommandManager.InvalidateRequerySuggested();
  27:    }
  28:  
  29:    static void RootVisualMouseAction(object sender, MouseButtonEventArgs e)
  30:    {      
  31:       CommandManager.InvalidateRequerySuggested();
  32:    }
  33:  
  34:    private static void Detatch()
  35:    {
  36:       if(_rootVisual == null)
  37:          return;
  38:  
  39:       _rootVisual.RemoveHandler(UIElement.MouseLeftButtonDownEvent, _mouseActionHandler);
  40:       _rootVisual.RemoveHandler(UIElement.MouseLeftButtonUpEvent, _mouseActionHandler);
  41:       _rootVisual.RemoveHandler(UIElement.KeyDownEvent, _keyActionHandler);
  42:       _rootVisual.RemoveHandler(UIElement.KeyUpEvent, _keyActionHandler);
  43:    }
  44: }

This naive implementation can be setup in the application class for your Silverlight project:-

   1: RootVisual = new RelayCommandDemoView();
   2: WpfCanExecuteOMatic.AttachTo(RootVisual);

 

 

Version 2: Constantly call InvalidateRequerySuggested on the Dispatcher.. (which sucks) [Ideally we would call it on application idle but I have not been able to determine a way to get such an event].

   1: public static class PseudoIdleOMatic
   2: {
   3:    public static void Start()
   4:    {
   5:       ApplicationDispatcher.Current.BeginInvoke(InvalidateRequerySuggested);
   6:    }
   7:    
   8:    private static void InvalidateRequerySuggested()
   9:    {
  10:       CommandManager.InvalidateRequerySuggested();
  11:       ApplicationDispatcher.Current.BeginInvoke(InvalidateRequerySuggested);
  12:    }
  13: }

 

Source code and samples can be found here.

Silverlight Commands - Routing and Command Bindings

The aim of this post (and the next) is to provide insight (and code!) into the implementation of WPF-esque commanding patterns using Silverlight technology. Several ICommand implementations, such as the Prism DelegateCommand<T> already exist out in the wild, but fail to address the routing and CommandBinding needs of developers migrating from the WPF platform.  The library and samples can be downloaded from here.

Out of the box Silverlight provides minimal support for commanding - on the bright side however it does provide an interface similar to one from WPF to build upon.

image 

 

Routing in Action

Before diving into technical details, it is probably worth throwing together a typical demo app showing something ‘typical’ one might see in WPF.

clip_image002

The application consists of two ‘DataControls’ (instances of which are contained within the borders) that utilise an implementation of RoutedCommand.  In the example below, the command is exposed as a property (as opposed to a field) for databinding purposes (and demonstrates how to get around the lack of x:Static support in Silverlight).

clip_image002[12]

The interesting thing to note here is that the behaviours of the command have not been defined yet - there is no ‘Execute’ or ‘CanExecute’ body provided with the RoutedCommand.  In WPF one would typically expect command invocations to bubble up the visual tree until finding something to handle them.  The provided Silverlight commanding API provides for a similar effect. 

Taking a look at the code-behind for the main page demonstrates how in this instance the SaveCommand is bound to logic.  Note how the logic is handled outside of the user control that uses the command.

clip_image002[14]

In a similar manner to WPF, the CommandManager can be used to notify all the commands they should re-evaluate their CanExecute state, and it would be feasible to hook onto events such as keydown/mousemove etc to invoke InvalidateRequerySuggested in a similar manner to WPF for ‘automated’ re-evaluation of command states.

Now we have seen a small demonstration of the framework, let’s take a closer look at the detail.

CommandBinding

clip_image002[16]

CommandBindings are really about being able to separate the invoked actions away from the definition of the command itself.

There are a few things to note here:

·         The command in the above example is publically and statically available, but does not have to be.

·         The third parameter is optional, if a CanExecute handler is omitted – the framework will assume the command can always execute.

·         If the third parameter is supplied, e.CanExecute must be set to true in order for the command to be executable.

·         Any number of command bindings may exist for a command.

In practice a CommandBinding enables a command to become context aware once it is associated with something, be it a presenter or view etc.  For example, in the snippet below a binding for the ‘ShowAllWorkItemsCommand’ is associated with the ‘shell’; when the ‘shell’ executes that command, those behaviours defined in that binding will be invoked.  Other components can provide different bindings for the same command to provide different behaviours, with each component behaving independently even though they are all effectively using the same command.

clip_image002[18]

 

RoutedCommand

clip_image002[20]

Unlike DelegateCommand<T> provided with Prism, we do not provide the bodies of the behaviours within the command definition itself, as that information is defined in the command bindings (see previous example in CommandRouting).  A RoutedCommand defined without any CommandBindings will never execute as CanExecute will return false in those circumstances.

To supplement the ICommand implementation, RoutedCommand adds some concrete methods to allow commands to be context-aware:

clip_image002[24]

So, if a several elements provided different bindings for the same command, calls to these methods will end up being delegated to the respective binding, based on the context passed in.

CommandRouter

So how are the statically defined commands aware of their bindings?  This is where the CommandManager and CommandRouter come into play. 

Whenever a RoutedCommand queries its state or invokes an action, it requests a CommandRouter from the CommandManager, and delegates its requests to the obtained CommandRouter.  The CommandManager exposes a default CommandRouter to provide support for command bubbling similar to WPF. The CommandRouter (an ICommandRouter) can be substituted for any custom routing that may be required; for example, a routing strategy could be introduced to provide support for command tunnelling.

An example of a non-contextual command binding in its simplest form:-

clip_image002[26]

A test demonstrating contextual command bindings:-

image

 

ICommandBindingSource

clip_image002[28]

As previously mentioned, the default CommandRouter provides a bubbling effect similar to WPF.  The basic mechanics are as follows:-

·         When a RoutedCommand is invoked, it delegates the request to the CommandRouter.

·         The CommandRouter determines if the passed context supports ICommandBindingSource.

·         If the passed context is a UI element, it will walk the parent visual tree until it finds something supporting ICommandBindingSource (e.g. the page).

·         Once an ICommandBindingSource is found, it will request the CommandBinding for the Command and execute behaviours accordingly.

An important note regarding realization of ICommandBindingSource is that the bindings do not necessarily have to live on the type implementing the interface.  For example, it may the View that implements the interface, but this could easily delegate straight down to an underlying presenter should you prefer to keep the command bindings out of the UI.

 

Command Behaviour

image

The commanding infrastructure provided with Prism introduced a neat WPF way of attaching commands to UI elements.  A modified implementation of this is provided to allow RoutedCommands to be hooked up in a similar manner.  Most of the code from Prism remains unchanged, however changes were required to allow state synchronization with CommandManager.InvalidateRequerySuggested. It is vital therefore when using behaviours to attach commands to visual elements to use the behaviours provided in iMeta.Windows.Commands, otherwise weak references will get collected for the event handlers and the visual elements will not react to CanExecuteChanged.

Conclusion

The provided framework allows for command bubbling, custom routing, centralized management of state change notification and separation of command logic from their definitions.  The sample provided may not be an ideal architecture, as many would opt for keeping as much code out of the UI as possible - I will cover an alternative commanding approach with an MVVM spin in my next post.  For those WPF developers wanting to migrate existing applications to Silverlight that require command routing (and maybe custom routing), then hopefully this post will be of use.

 

IIS 7 Failing to Serve WCF Service

IIS 7 doesn’t serve up WCF services out-of-the box.  Many thanks to this guy for pointing that out and providing the solution!

Run the following from an elevated command prompt:

"%windir%\Microsoft.NET\Framework\v3.0\Windows Communication
Foundation\ServiceModelReg.exe" -r -y

Silverlight TextBox Databinding Bug Workaround

Whilst developing a LOB Silverlight application, one of our testers pointed out that single character changes were not getting 'saved'. This seemed odd as we were just doing ordinary Databinding, albeit through various presenters and ViewModels. Interestingly I spotted a few articles that seemed to be described the issue we were seeing:

http://silverlight.net/forums/p/35136/105682.aspx

http://forums.lhotka.net/forums/thread/28597.aspx

http://karlshifflett.wordpress.com/2008/04/12/silverlight-2-lostfocus-and-data-binding-bugs/

 

To investigate the cause I reduced the example down to barebones.

Page.xaml

<UserControl x:Class="SilverlightApplication3.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <StackPanel x:Name="LayoutRoot" Background="White">
      <TextBlock Margin="5" Text="{Binding Forename}"/>
      <TextBlock Margin="5" Text="{Binding Surname}"/>
      <TextBox Margin="5" Text="{Binding Forename, Mode=TwoWay}"/>
      <TextBox Margin="5" Text="{Binding Surname, Mode=TwoWay}"/>      
   </StackPanel>
</UserControl>

Page.xaml.cs 
 
namespace SilverlightApplication3
{
   public partial class Page : UserControl
   {
      private Person _model;

      public Page()
      {
         InitializeComponent();
         
         Person person = new Person() { Forename = null, Surname = null };
         this.DataContext = person;

         person.Forename = "Andy";
         person.Surname = "Boyne";
      }

      public Person Model
      {
         get { return _model; }
         set
         {
            if(value!=_model)
            {
               _model = value;
               DataContext = _model;
            }
         }
      }
   }

   public class Person : INotifyPropertyChanged
   {
      private string _forename;
      private string _surname;
      public event PropertyChangedEventHandler PropertyChanged;

      public string Forename
      {
         get { return _forename; }
         set
         {
            if(value!=_forename)
            {
               _forename = value;
               RaisePropertyChanged("Forename");
            }
         }
      }

      public string Surname
      {
         get { return _surname; }
         set
         {
            if (value != _surname)
            {
               _surname = value;
               RaisePropertyChanged("Surname");
            }
         }
      }

      private void RaisePropertyChanged(string propertyName)
      {
         if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }
   }
}

 

If you run the sample, and then enter a single character change into either textbox you will notice the binding fails to update. Enter more characters and the binding seems to work again.
In the example above the DataContext it is set in the constructor – but the problem still exists regardless of where this is set (e.g. it could be set externally via a presenter)

 

The Workaround

 

Dispatcher.BeginInvoke(() => this.DataContext = _model);

Setting the DataContext via the Dispatcher now causes single character changes to update the bindings.

TFS Build Failing to Publish Test Results?

If after setting up a new build box you discover your build is failing because the test results are failing to get published, e.g:-

Waiting to publish... (TaskId:193)

Publishing results of test run ..... to ......

.Publish operation failed. (TaskId:193)

Publish operation failed. (TaskId:193)

... then you have not given the TFS service account permissions on the drop location of your build.

MCTS (070-502 WPF Application Development) Success!

One of the great things about working for iMeta is the fact they encourage you to take professional qualifications. Not only this, they actually pay for it and give you time to study. As a result of this, I have now obtained my second Microsoft qualification, this time in WPF – rock on!

Overall the exam is not too difficult provided you have had experience working with WPF and have read this book from cover to cover - the vast majority of the questions are Xaml based so make sure you are comfortable with that side of things.

Good luck to all others wishing to take this exam.

How to create a solution that shares code with Silverlight.Net

Following on from my last post regarding Silverlight for business, I thought I would share a technique that enables code (and tests) to be shared between Silverlight and standard .Net components. Enjoy!

 

Key Concepts

The solution is structured to ensure it can target the Desktop .Net and Silverlight .Net runtimes concurrently. It is anticipated the majority of source can be shared across the platforms, though it is inevitable there will be some source that exists solely for either platform.

Folder Structure

  • The root for the code is 'Source'.
  • Each solution is isolated inside a folder beneath source. In the example above, the 'iMeta' solution is located within the 'iMeta' folder.
  • Each solution folder has two branches for the different runtimes. (DotNet/Silverlight)
  • Each project is kept in its own folder beneath the runtime branches.
  • Unit Test projects are isolated beneath a 'Tests' folder. This will enable better management of check-in policies.

     

Solution Structure

  • Solution folders isolate the different runtime branches. (.Net/Silverlight)
  • A 'Tests' folder isolates unit tests from the main source branches.
  • In general, the runtime branches should mirror each other, with the inclusion of the term 'Silverlight' in the assembly name. This enables you to easily identify which assemblies in a bin folder are Silverlight ones (otherwise they'll be called the same, have the same version, and reflector will show they have the same code!)

 

Project Structure

Assembly Name and Namespace

  • Mirrored assemblies share the same namespace, but not the same assembly name.
    • As MSBuild dumps built assemblies in the same location, without customising the project files it is not possible to isolate the different platforms into separate folders and so the same-named-assemblies would overwrite each other. Customising the project files would require deploying a ProjectItemTemplate to team members for each project type. This would inevitably be an annoying error prone step.

       

    • As stated above, it is just easier to name the Silverlight assemblies something different so you can identify them.

Signing

  • The key for signing assemblies resides in the solution folder, and is added to the solution as a Solution Item.

  • Each project references the key as a link and signs against this reference.

 

Code Sharing

  • Projects that mirror each other should share code. Although Desktop.Net and Silverlight.Net cannot share assembly references, they can share source code.
  • To share code, 'Add Existing Item', navigate to where the shared code primarily exists, and 'Add as Link'.
  • By default, Silverlight projects define a SILVERLIGHT constant which can be used for conditional compilation.

Test Sharing

  • In a similar manner to sharing code, Test code can also be shared via 'Add Existing Item'-> 'Add as Link'.

NOTE: One thing to bear in mind when creating unit tests for the Silverlight class libraries is that there is no integrated unit testing framework for Silverlight. Instead you have to create a 'Silverlight Test Application'. The project template and binaries for the Silverlight unit testing framework can be found here.

For our purposes, we placed a copy of those binaries in our 'External' folder for the Silverlight branch so other developers on a project can find them easily.

 

Continuous Integration

Silverlight Unit tests will not run in CI builds due to lack of integration support from Microsoft, though there is a rumour this will be included in a future release. In the meantime, running the Silverlight test suite can be a manual task that is achieved by launching the test project. Alternatively, if you have some spare time, there is a workaround to get it running on your build server. Needless to say, all tests that pass in the Desktop.Net branch should also pass in the Silverlight.Net branch.

A Practical Business Application Using Silverlight

Today, a Silverlight demo we developed became available on the Microsoft Silverlight Showcase. The purpose of our demo is not to show how wizzy a video stream can be, nor is it to demonstrate a wacky or futuristic UI; it is simply a practical demonstration of a business application developed using Silverlight. It combines the paper based form, guidance and calculations found on the UK HM Revenue & Customs site.

Please feel free to have a look!

DISCLAIMER! The application is for demonstration purposes only and should not be used when submitting an SA970 to UK HM Revenue and Customs.

Scrum for Team System – Hidden MSBuild Problem (with solution)

Recently I set up a new TFS project using the Scrum for Team System Template, and spotted a bit of a problem whilst scouring the log for a broken build:

Done executing task "CreateNewWorkItem" -- FAILED.
...
...
...

C:\Program Files\MSBuild\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets(1422,5,1422,5): warning : TF42097: A work item could not be created due to a field error. The following fields have incorrect values: Field: 'Reason' Value: 'Build Failure'

C:\Program Files\MSBuild\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets : warning MSB4018: The "CreateNewWorkItem" task failed unexpectedly.

C:\Program Files\MSBuild\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets : warning MSB4018: Microsoft.TeamFoundation.Build.Tasks.TaskException: TF42097: A work item could not be created due to a field error. The following fields have incorrect values: Field: 'Reason' Value: 'Build Failure' --->
...
...

 

MSBuild was unable to create a new work item about the broken build. The problem lies in the TFSBuild.proj file produced when creating a build definition – it always assumes there is a 'Reason' field it can write to when creating a work item:

<WorkItemFieldValues>System.Reason=Build Failure; ...

The solutuion is simply to remove the field assignment ("System.Reason=Build Failure;") from the list.