Showing posts with label Silverlight. Show all posts
Showing posts with label Silverlight. Show all posts

Thursday, 27 October 2011

Handling WCF faults in Silverlight

Here’s a quick reminder to self about handling SOAP faults in Silverlight applications, something that happened recently and I forgot a simple step.

Before going any further read this (it will probably answer all your questions): Creating and Handling Faults in Silverlight

Firstly, I had a WCF service that was exposing faults contracts using the [FaultContract] attribute.

[ServiceContract(Namespace = "http://some_namespace_here/ConfigurationService/2011/10/01/01", Name = "ConfigurationService")]
public interface IConfigurationService
{
    [OperationContract(Name = "GetConfiguration")]
    [FaultContract(typeof(MyFault))]
    [FaultContract(typeof(ValidationFault))]
    ConfigurationResponse GetConfiguration(ConfigurationRequest request);
}

The service was implemented along with fault types, for example:

[DataContract(Namespace = "http://some_namespace_here/WIRM/2011/10/01/01", Name = "MyFault")]
public class MyFault
{
    [DataMember(IsRequired = true, Name = "FaultDetail", Order = 0)]
    public string FaultDetail { get; set; }

    [DataMember(IsRequired = true, Name = "FaultCode", Order = 1)]
    public string FaultCode { get; set; }
}

The problem was that back in Silverlight when I was handling exceptions generated from service calls the exception didn’t have the specific detail of the fault. The trick to making this work is in the article linked to above. We chose to use the “alternative client HTTP stack” approach by adding this to App.xaml.cs:

public partial class App : Application
{
    public App()
    {
        bool registerResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
        InitializeComponent();
    }
}

Thereafter it was possible to get at the actual fault exceptions and take advantage of specific exception details:

private void ClientGetConfigurationCompleted(object sender, GetGetConfigurationEventArgs e)
{
    if (e.Error == null)
    {
        // Do normal processing here...
        return;
    }
            
    if (e.Error is FaultException<ValidationFault>)
    {   
        var ex = e.Error as FaultException<ValidationFault>;
        // Do stuff with validation errors (via ex.Detail)
    }
            
    if (e.Error is FaultException<MyFault>)
    {
        var ex = e.Error as FaultException<WirmFault>;
        // Do stuff with MyFault (via ex.Detail)
    }
}

That’s it.

Wednesday, 19 October 2011

Feature layers not displaying when using the ArcGIS Silverlight API

I have been using the ArcGIS Silverlight API to create a mapping application. To provide some context, the application had to show a pipe network together with valves and other associated assets. The pipes were to be selectable in the interface so that pipe asset IDs could be used to drive queries and other processing.
In order to render the valves etc. I chose to use the ESRI FeatureLayer. I also used a FeatureLayer with a Mode of SelectionOnly for pipe selection.
One of the requirements of the system was that background imagery be used. This was created using an ArcGISDynamicMapServiceLayer. The feature layers and the background layer were taking their data from different ArcGIS services.
Although my code was using MVVM the scenario could be replicated in XAML like this (this is the map control XAML only with a number of layers omitted):
<esri:Map x:Name="AWMap">
    <esri:Map.Layers>
        <esri:ArcGISDynamicMapServiceLayer 
                 ID="BaseLayerStreets" 
                 Url="http://servername/ArcGIS/rest/services/projectname/backgroundservicename/MapServer" />
        
        <esri:FeatureLayer ID="Hydrants" 
            Url="http://servername/ArcGIS/rest/services/projectname/featureservicename/MapServer/0"
            Where="1 = 1"
            Mode="OnDemand"
            Renderer="{StaticResource ValveRenderer}">
            <esri:FeatureLayer.Clusterer>
                <esri:FlareClusterer 
                    FlareBackground="Red" 
                    FlareForeground="White" 
                    MaximumFlareCount="9" />
            </esri:FeatureLayer.Clusterer>
        </esri:FeatureLayer>
    
    </esri:Map.Layers>
</esri:Map>

The problem

The problem was that as soon as the background layer was included the feature layers simply didn’t render. Handling the feature LayerInitialized and InitializationFailed events showed that the feature layers were initialised and that no errors were reported.
So what was going on?

The solution

After hours of head-scratching I reread the ESRI documentation and this popped out:
“By default, the first layer with a valid spatial reference defines the spatial reference for the map. Dynamic ArcGIS Server map and image services as well as feature layers (FeatureLayer) will be reprojected to the map's spatial reference if necessary.” - http://help.arcgis.com/en/webapi/silverlight/help/index.html#/Creating_a_map/016600000011000000/
When I checked the metadata for the 2 services in the ArcGIS Services Directory I noticed that the Spatial Reference was different for the 2 services. So, I changed the XAML to something like this (note lines 2 to 8):
<esri:Map x:Name="AWMap">
    <esri:Map.Extent>
        <esri:Envelope XMin="111111" YMin="222222" XMax="333333" YMax="444444" >
            <esri:Envelope.SpatialReference>
                <esri:SpatialReference WKID="27700"/>
            </esri:Envelope.SpatialReference>
        </esri:Envelope>
    </esri:Map.Extent>
    <esri:Map.Layers>
        <esri:ArcGISDynamicMapServiceLayer 
                 ID="BaseLayerStreets" 
                 Url="http://servername/ArcGIS/rest/services/projectname/servicename/MapServer" />
        
        <esri:FeatureLayer ID="Hydrants" 
            Url="http://servername/ArcGIS/rest/services/projectname/servicename/MapServer/0"
            Where="1 = 1"
            Mode="OnDemand"
            Renderer="{StaticResource ValveRenderer}">
            <esri:FeatureLayer.Clusterer>
                <esri:FlareClusterer 
                    FlareBackground="Red" 
                    FlareForeground="White" 
                    MaximumFlareCount="9" />
            </esri:FeatureLayer.Clusterer>
        </esri:FeatureLayer>
    
    </esri:Map.Layers>
</esri:Map>
The result was that the missing feature layer magically appeared.
So, if you are having problems with missing feature layers check your spatial references. My guess is you should change the spatial references at the server to prevent re-projection on the client; performance may be better.

Wednesday, 18 May 2011

MEF basics

I’m digging into the Managed Extensibility Framework (MEF) and need to keep track of some simple terms, definitions and concepts. This post is just an aide-mémoire so don’t expect any detail. I’ve crushed the MEF documentation into some bullet points.

What is MEF?

“MEF offers discovery and composition capabilities that you can leverage to load application extensions.” *
The basic namespace for everything MEF is System.ComponentModel.Composition.

Basic terms and definitions

  • Catalog
    • Responsible for discovering extensions (ComposableParts)
    • Assembly Catalog
      • Discovers all the exports in a given assembly
    • Directory Catalog
      • Discover all the exports in all the assemblies in a directory
      • Does a one-time scan of the directory and will not automatically refresh when there are changes in the directory (can call Refresh() to rescan)
      • Not supported in Silverlight
    • Aggregate Catalog
      • Use when a combination of catalogs is needed
    • Type Catalog
      • Discovers all the exports in a specific set of types
    • Deployment Catalog
      • Silverlight only
      • For dynamically downloading remote XAPs
  • CompositionContainer
    • Interacts with Catalogs
    • Resolves a part's dependencies and exposes Exports to the outside world
  • ComposablePart
    • A composable unit within MEF
    • Offers up one or more Exports
    • May depend on one or more externally provided Imports
    • Attributed with the [System.ComponentModel.Composition.Export] and [System.ComponentModel.Composition.Import] attributes in order to declare their exports and imports.
    • Either added to the container explicitly or created through the use of catalogs
    • A common pattern is for a ComposablePart to export an interface or an abstract type contract rather than a concrete type
      • Allows the importer to be decoupled from the specific implementation of the export
  • Contract
    • The bridge between exports and imports
    • A contract is a string identifier
    • If no contract is specified, MEF will implicitly use the fully qualified name of the type as the contract
    • Every export has a contract, and every import declares the contract it needs
  • Contract Assembly
    • An assembly which contains contract types that extenders can use for extending your application
  • Exports
    • Composable Part export
      • Used when a Composable Part needs to export itself
      • Decorate the Composable Part class with the[Export]
    • Property export
      • Decorate a property with the [Export] attribute
      • Allows exporting sealed types such as the core CLR types, or other third party types
      • Allows decoupling the export from how the export is created
      • Allows having a family of related exports in the same Composable Part
    • Method export
      • Methods are exported as delegates which are specified in the Export contract
      • Allows finer grained control as to what is exported
      • Shields the caller from any knowledge of the type
      • Can be generated through light code gen
    • Inherited Exports
      • Base class / interface defines exports which are automatically inherited by implementers
      • Use [InheritedExport]
    • Lazy Exports
      • Can delay instantiation
      • Can prevent recursive composition down the graph
      • Import an [System.Lazy<T>] instead of [T] directly
  • Imports
    • Property import
      • Decorate the property with [Import]
    • Constructor parameters
      • Specify imports through constructor parameters
      • Add [ImportingConstructor] to the constructor
      • Add parameters to the constructor for each import
    • Field imports
      • Decorate the field with [Import]
    • Optional imports
      • MEF allows you to specify that an import is optional ([Import(AllowDefault=true)])
      • The container will provide an export if one is available otherwise it will set the import to Default(T)
    • Importing collections
      • Can import collections with the [ImportMany] attribute
      • All instances of the specific contract will be imported from the container and added to the collection
      • Recomposition
        • As new exports become available in the container, collections are automatically updated with the new set
        • [ImportMany(AllowRecomposition=true)]
    • IPartImportsSatisfiedNotification
      • Defines an OnImportsSatisfied method, which is called when all imports that could be satisfied have been satisfied

References

* MEF Overview

See also

Managed Extensibility Framework, on CodePlex

Friday, 16 July 2010

Comparing the MVC, MVP and MVVM patterns

Having spent some time looking at several presentation technologies recently I thought I should take stock of a number of design patterns that are frequently referenced.

Silverlight and WPF are often associated with the Model-View-ViewModel (MVVM) pattern (see frameworks such as Prism, MVVM Light, Caliburn etc). ASP.Net MVC of course utilises Model-View-Controller. In the past I have tried to overcome some of the short-comings of ASP.Net Web Forms using variations of the Model-View-Presenter (MVP) pattern.

Each of these patterns tries to address a number of problems:

  1. Where and how do we maintain state in the UI?
  2. Where does business logic live in the application and how is it invoked?
  3. How do we keep the UI synchronised with changes to the data and between UI elements?
  4. How can we ensure good separation of concerns and create loosely coupled testable code?

So the question is, how do they compare?

Note: There are variations on the theme here so there may be alternatives especially with MVP (e.g. Passive View, Supervising Controller, Front Controller).

mvc-mvp-mvvm

MVC MVP MVVM
Input is routed to the Controller.

The Controller decides which View to render and builds the Model which is bound to the View.

A Controller can choose to render one of many Views.

The View has no knowledge of its Controller.

Business logic exists in the Controller.

MVC is useful when state can’t be maintained between user input requests (e.g. over HTTP – a stateless protocol).
Input is routed to the View.

The Presenter updates the View usually in response to events raised by the View.

State is effectively stored in the View.

Business logic exists in the Presenter.
Input is routed to the View.

The View knows about nothing but the ViewModel.

The ViewModel knows about nothing but the Model.

The View gets its data from the ViewModel, not the Model itself. This is generally accomplished by data binding. 

State and business logic exist in the ViewModel.

The ViewModel can be thought of as an abstract representation of the UI.

MVVM is useful when state can be maintained between UI requests (e.g. Silverlight, WPF).

Sunday, 11 July 2010

Screen Conductor and other patterns

Silverlight and WPF development have lead to the uptake of a number of development patterns many of which were first introduced by Martin Fowler or which are variations of them. This post contains notes about the various patterns that are appearing in frameworks like Caliburn.Micro or Prism.

These patterns are put together to form a presentation framework.

Firstly, there is the Application Controller:

“A centralized point for handling screen navigation and the flow of an application.” http://martinfowler.com/eaaCatalog/applicationController.html (Martin Fowler)

The Application Controller is often comprised of a number of elements such as:

  • Screen(s)
  • Screen Factories
  • Screen Factory Registry
  • Screen Conductor
  • Screen Collection
  • Subject

Screen

  • The class that handles coordinates the Model, View and ViewModel.
  • Coordinates the marrying of a View to a ViewModel (the View doesn’t know about the ViewModel, the ViewModel doesn’t know about View).
  • Implements the IScreen interface.
IScreen
  • An interface that all Screens will implement.
  • Requires methods such as CanLeave() and CleanUp().

Screen Factory

  • There is a one-to-one relationship between Screen Factories and Screens.
  • Screen Factories implement the IScreenFactory interface
  • The Screen Factories are registered with the presentation framework (i.e. the Screen Factory Registry singleton class).
  • Screen Factories are used by the Screen Conductor to instantiate screens.
IScreenFactory
  • Requires a CreateScreen() method.

Screen Factory Registry

  • The Screen Factory Registry contains a registry of all of the screen factories.
  • Modules can register their Screen Factory classes with the Screen Factory Registry.
  • The Screen Factory Registry has methods including GetFactory(), HasFactory(), and a Screen Factory Dictionary

Screen Conductor

  • The Screen Conductor coordinates the creation and destruction of screens.
  • The Screen Conductor makes use of the Screen Factory Registry which it uses to create Screens as necessary.
  • Screen creation includes screen visibility, screen location, loading Subjects into screens, etc.
  • The Screen Conductor has a Screen Collection; a collection of all activated screen instances.
  • The Screen Conductor is often a singleton.

Screen Collection

  • The Screen Conductor has a Screen Collection which contains all of the activated screen instances.
  • The Screen Collection is maintained by the Screen Conductor.

Subject

  • The Subject is analogous to the Model; it’s what is required by the screen to fulfil its purpose.

 

After the Application Controller there is the Application Shell.

Application Shell

  • The Application Shell is analogous to the main form in the application.
  • The responsibility of the shell is to hold the main components of the user interface (e.g. menus, ribbons, panels, docking managers, etc.) for the screens that get activated later. 

 

There sometimes are other elements that are combined with the above as part of the Presentation Framework.

Bootstrapper

  • The Bootstrapper is responsible for instantiating elements like the Application Shell and the IoC container (should one be used).
  • The Bootstrapper can also be used to activate services used by the application (e.g. caching service).

Wednesday, 30 June 2010

Binding Modes in Silverlight

There are 3 binding modes in Silverlight (identified by the BindingMode enumeration):

  • OneTime - bindings update the target with the source data when the binding is created
  • OneWay - bindings update the target with the source data when the binding is created and anytime the data changes. This is the default mode.
  • TwoWay - bindings update both the target and the source when either changes. Alternately, you can disable automatic source updates and update the source only at times of your choosing. When the binding is created, the target property is updated from the source.

In OneWay or TwoWay bindings, the source object must implement INotifyPropertyChanged in order for the target to update when the source changes.

For TwoWay bindings, changes to the target do not automatically propagate to the source, except if the binding target is the Text property. In that case, the update happens only when the TextBox loses focus. In other words, the in-memory object to which the TextBox is bound isn’t modified until the TextBox loses focus whereas other elements perform their updates immediately (e.g. the user moves a bound slider control). If you need a TextBox to update as the user types you must implement an event handler on the TextBox TextChangedEvent. For example:

private void myTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    BindingExpression exp = myTextBox.GetBindingExpression(TextBox.TextProperty);
    exp.UpdateSource();
}

For OneTime and OneWay bindings, calls to SetValue automatically change the target value and delete the binding.

See:

Friday, 25 June 2010

WCF RIA Services basics

This post is mainly concerned with the basics of WCF RIA Services and is intended to serve as a aide memoire for terms etc. It will be added to over time.
Some definitions:
  • Project Link
    • The server project references the domain services, shared code etc. defined on the server side.
    • Code is generated in the client project at compile time linking the client and the server.
  • Entities
    • Defined on the server and generated client-side.
    • Validation etc. also generated on the client side (i.e. you just maintain the single server-side definition).
    • Used to marshal the data across the WCF service.
    • Can be created with Entity Framework, LINQ to SQL, or POCOs.
  • Domain Service
    • Defines the operations supported on the server side (e.g. CRUD operations).
    • Can be arbitrary operations to be invoked on the server from the client exposed by WCF.
  • Domain Context
    • The client side counterpart to the Domain Service.
    • Generated code on the client side.
    • Contains a WCF proxy that makes the service calls.
    • Manages creating the queries to be executed on the server side, entity change tracking etc.
  • Domain Data Source
    • Used to execute queries and submit changes to the server side.
    • Associated with the domain context.
    • Makes calls through the domain context to query and update entities.
    • Facilitates direct data binding from XAML.
Entities or entity collections retrieved are cached through the domain context on the client side. Changes (i.e. the addition, deletion or update of entities) are effectively ‘stored’ in the Domain Context until the changes are flushed through to the database. In other words, the Domain Context must be kept around long enough to submit the changes.
The Domain Context Load and SubmitChanges execute asynchronously. They take a thread from the thread pool, make the necessary calls to the server, and when those calls complete the work is automatically marshalled back to the UI thread to modify the entity collections and subsequently update the UI (probably via INotificationChanged).
However, it would be prudent to assume at least the possibility of problems. A couple of strategies that can be employed to get around this are:
  • Subscribe to the Completed event obtained from the LoadOperation or SubmitOperation obtained from Load or SubmitChanges.
  • Call an overload of the Load or SubmitChanges that takes an Action<LoadOperation> or Action<SubmitOperation> (i.e. supply call-backs).

Attributes

When creating the Domain Service (server side) adding the EnableClientAccess attribute will cause client side code to be generated at compile time.
Operations in the Domain Service can be decorated with attributes to identify their purpose (e.g.  create, read, update or delete and entity instance).
Authentication and authorisation can be enforced using attributes (the attributes can be specified at the service or operation level):
  • RequiresAuthentication - prevents anonymous users from accessing a service to perform an operation.
  • RequiresRole - ensures that the current principal belongs to one of the specified roles.

Convention over configuration

By default WCF RIA Services uses convention over configuration to find appropriate operations defined in the Domain Service.  There are a set of named method prefixes WCF RIA Services is looking for (e.g. Update***, Insert***, Delete***).
As an alternative attributes can be used to decorate methods and indicate what they are to be used for (i.e. configuration).

Authentication and authorisation

On the client authentication functionality is accessed through a class called WebContext, a class that represents functionality provided by the web server.
Authentication services implement the IAuthentication interface. An implementation of an authentication service will use a DomainContext to work against the corresponding DomainService implementing IAuthentication on the server.
There are 2 approaches to implementing authentiaction:
1. Derive from the out-of-box AuthenticationService base class. This provides a default implementation that leverages the asp.net membership, roles and profile infrastructure.
2. Implement IAuthentication on your domain service and do whatever you like based on your unique scenarios when implementing Login, Logout and other methods of the interface. This is especially useful if you're not using the asp.net infrastructure services or want to use some custom auth mechanism.
See http://www.nikhilk.net/Entry.aspx?id=262 and http://www.nikhilk.net/RIAServices-Authorization.aspx.
Authorisation can be further controlled using attributes (see above).

Monday, 21 June 2010

Physics engines for Silverlight

I’ve been looking around at physics engines for Silverlight and a couple have surfaced as being potentially usable.

Box2D

Although originally a C++ project (http://www.box2d.org/) there are C# ports available. One example can be found in the behaviours library available here: http://blois.us/blog/2010/03/labyrinth-sample-for-windows-phone.html. This code includes a Box2D.SL project.

What is interesting about this Box2D implementation is that it has been demonstrated to work on the Windows Phone 7.

Farseer

The Farseer Physics Engine is an easy to use 2D physics engine designed for Microsoft’s XNA and Silverlight platforms. The Farseer Physics Engine focuses on simplicity, useful features, and enabling the creation of fun, dynamic games.

 http://farseerphysics.codeplex.com/documentation

I think Farseer has been used by the developer of Silversprite, the platform for allowing XNA games to run in Silverlight.

Physics Helper for Silverlight, WPF, Blend, and Farseer

The Physics Helper for Blend, Silverlight and WPF contains several Behaviors and controls which allow you to draw objects in Expression Blend 3, and have those objects translated directly into Physics objects using the Farseer Physics Engine. This can be a great timesaver for creating games, as it is traditionally difficult to line up underlying physics bodies and geometries with your Blend artwork.

http://physicshelper.codeplex.com/

Monday, 14 June 2010

Gradient brushes in Silverlight

Before going any further look at this for an explanation of brushes, including gradients:

http://msdn.microsoft.com/en-us/library/cc189003%28VS.95%29.aspx

It’s useful to visualise what’s going on with gradient brushes so here is an example application with 3 pages each showing a rectangle with either a linear gradient fill or a radial gradient fill. There are 2 examples of linear gradients and one of a radial gradient. Of the linear gradient examples one has 2 gradient stops and the other 3.

Move the sliders to see the effect of different parameters on a gradient.

Get Microsoft Silverlight

The following XAML snippets show rectangles from the 3 examples so you can see how the binding is working.

Radial gradient

<Rectangle x:Name="rectFilled" Width="200" Height="100" Margin="0,5" HorizontalAlignment="Left">
  <Rectangle.Fill>
    <RadialGradientBrush GradientOrigin="{Binding GradientOrigin}" Center="{Binding Center}" RadiusX="{Binding RadiusX}" RadiusY="{Binding RadiusY}">
      <GradientStop x:Name="yellowGradientStop" Color="Yellow" Offset="{Binding YellowOffset}" />
      <GradientStop x:Name="redGradientStop" Color="Red" Offset="{Binding RedOffset}" />
    </RadialGradientBrush>
  </Rectangle.Fill>
</Rectangle>

Linear gradient with 2 gradient stops

<Rectangle x:Name="rectFilled" Width="200" Height="100" Margin="0,5" HorizontalAlignment="Left">
  <Rectangle.Fill>
    <LinearGradientBrush x:Name="lgbGradient" StartPoint="{Binding StartPoint}" EndPoint="{Binding EndPoint}">
      <GradientStop x:Name="yellowGradientStop" Color="Yellow" Offset="{Binding YellowOffset}" />
      <GradientStop x:Name="redGradientStop" Color="Red" Offset="{Binding RedOffset}" />
    </LinearGradientBrush>
  </Rectangle.Fill>
</Rectangle>

Linear gradient with 3 gradient stops

<Rectangle x:Name="rectFilled" Width="200" Height="100" Margin="0,5" HorizontalAlignment="Left">
  <Rectangle.Fill>
    <LinearGradientBrush x:Name="lgbGradient" StartPoint="{Binding StartPoint}" EndPoint="{Binding EndPoint}">
      <GradientStop x:Name="yellowGradientStop" Color="Yellow" Offset="{Binding YellowOffset}" />
      <GradientStop x:Name="blueGradientStop" Color="Blue" Offset="{Binding BlueOffset}" />
      <GradientStop x:Name="redGradientStop" Color="Red" Offset="{Binding RedOffset}" />
    </LinearGradientBrush>
  </Rectangle.Fill>
</Rectangle>

Tuesday, 8 June 2010

2D Matrix transforms in Silverlight

“A 3x3 matrix is used for transformations in a two-dimensional x-y plane. Affine transformation matrices can be multiplied to form any number of linear transformations, such as rotation and skew (shear), followed by translation. An affine transformation matrix has its final column equal to (0, 0, 1), so only the members in the first two columns need to be specified. Note that vectors are expressed as row-vectors, not column vectors.” *

Affine transformations preserve collinearity and relative distancing in a transformed coordinate space:

  • Points on a line will remain in a line after an affine transformation
  • Parallel lines remain parallel
  • Relative spacing or distancing will always maintain at a consistent ratio.

Affine transformations allow for repositioning, scaling, skewing and rotation. Things they cannot do include tapering or distorting with perspective.

The transformation matrix looks like this (default values in brackets):

M11 (1.0) M12 (0.0) 0
M21 (0.0) M22 (1.0) 0
OffX (0.0) OffY (0.0) 1

The elements ion the matrix map as follows:

  • M11 = X Scale
  • M12 = Y Skew
  • M21 = X Skew
  • M22 = Y Scale
  • OffX = translation on X axis
  • OffY = translation on Y axis

Or:

X Scale Y Skew 0
X Skew Y Scale 0
X translation Y translation 1

Note you cannot change the values of the 3rd column in the Matrix class (i.e. 0, 0, 1).

For example, to create a matrix that scales but changes no other parameters:

double scaleX = 0.5;
double scaleY = 0.5;
Matrix mx = new Matrix(scaleX, 0.0, 0.0, scaleY, 0.0, 0.0);

A quick bit of revision; the following is an identity matrix:

1 0 0
0 1 0
0 0 1

This applies no transformation whatsoever:

x' = x*1 + y*0 + 0
y' = x*0 + y*1 + 0

which reduces to

x' = x
y' = y

Note that the the matrix for the point will be [x, y, 1].

* Matrix Structure - http://msdn.microsoft.com/en-us/library/system.windows.media.matrix%28v=VS.95%29.aspx

See also:

Attached vs regular dependency properties

With dependency properties the backing store of the property is an object of type DependencyProperty instead of what would normally be a private field. Dependency properties can come in 2 forms: attached or not attached.

Regular dependency properties are set on a DependencyObject just like any other .NET property.

Attached dependency properties are associated with a DependencyObject (e.g. Grid) but are set on a separate DependencyObject, often a child of the DependencyObject that defines the attached property (e.g. Grid.Row, an attached property, is set on the children of a parent Grid).

An attached property is a concept defined by Extensible Application Markup Language (XAML). An attached property is intended to be used as a type of global property that is settable on any object…

…One purpose of an attached property is to allow different child elements to specify unique values for a property that is actually defined in a parent element. A specific application of this scenario is having child elements inform the parent element of how they are to be presented in the user interface (UI). *

When manipulating dependency properties in code the DependencyProperty.Register() method is used to register a normal unattached dependency property on a DependencyObject. DependencyProperty.RegisterAttached() is used to set an attached dependency property.

If your class is defining the attached property strictly for use on other types, then the class does not have to derive from DependencyObject. But you do need to derive from DependencyObject if you follow the overall WPF model of having your attached property also be a dependency property.

Define your attached property as a dependency property by declaring a public static readonly field of type DependencyProperty. You define this field by using the return value of the RegisterAttached method. The field name must match the attached property name, appended with the string Property, to follow the established WPF pattern of naming the identifying fields versus the properties that they represent. The attached property provider must also provide static GetPropertyName and SetPropertyName methods as accessors for the attached property; failing to do this will result in the property system being unable to use your attached property. * (my bold)

* http://msdn.microsoft.com/en-us/library/ms749011.aspx

See also http://stackoverflow.com/questions/910579/dependencyproperty-register-or-registerattached

Dependency property example

public string MyProperty 
{
    get { return (string)GetValue(MyPropertyProperty); }
    set { SetValue(MyPropertyProperty, value); } 
} 

public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register("MyProperty", typeof(string), typeof(MyClass), new PropertyMetadata(""));

The Register() static method accepts a class of type PropertyMetadata that, among other things, sets the default value of the property. Remember there is also a RegisterAttached() version for attached properties.

Differences between Silverlight and WPF

The differences between Silverlight and WPF reside in the metadata structure: Silverlight only supports the PropertyMetadata class here, while WPF supports several classes (all derived from PropertyMetadata).

Monday, 31 May 2010

UriMapper not working

When using the navigation framework in Silverlight I found the URI mapping was not working. Interestingly, the Tim Heuer example on the Microsoft Silverlight web site didn’t work either.

A UriMapper something like the following was declared in App.xaml:

<Application.Resources>
    <navcore:UriMapper x:Key="UriMapper">
        <navcore:UriMapping Uri="Uri1" MappedUri="/Views/Page1.xaml" />
        <navcore:UriMapping Uri="Uri2" MappedUri="/Views/Page2.xaml" />
    </navcore:UriMapper>
</Application.Resources>

Hyperlinks were declared in the MainPage.xaml looking something like this:

<StackPanel x:Name="LeftNav" Width="150" Orientation="Vertical"/>
    <HyperlinkButton Tag="Uri1" Content="Page 1" Click="HyperlinkButton_Click" />
    <HyperlinkButton Tag="Uri2" Content="Page 2" Click="HyperlinkButton_Click" />
</StackPanel>

The navigation frame was declared in the MainPage.xaml something like this:

<navigation:Frame x:Name="Frame" />

Code in the HyperlinkButton_Click event handler looked something like this:

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    var link = sender as HyperlinkButton;
    var tag = link.Tag as string;
    Frame.Navigate(new Uri(tag, UriKind.Relative));
}

Clicking on a link produced no effect in the Silverlight application (i.e. no navigation). In IE8 a JavaScript error was reported on the page. Details of the error were along the lines of:

Message: Unhandled Error in Silverlight Application Navigation is only supported to relative URIs that are fragments, or begin with '/', or which contain ';component/'.
Parameter name: uri at System.Windows.Navigation.NavigationService.NavigateCore(Uri uri, NavigationMode mode, Boolean suppressJournalAdd)
    at System.Windows.Navigation.NavigationService.Navigate(Uri source)
    at System.Windows.Controls.Frame.Navigate(Uri source)
    at System.Windows.Controls.Frame.Frame_Loaded(Object sender, RoutedEventArgs e)
    at MS.Internal.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)

... snip ...

The problem turned out to be that the UriMapper declared in App.xaml was not known to the navigation frame. The solution was to map the UriMapper on the frame in the MainPage.xaml:

<navigation:Frame x:Name="Frame" UriMapper="{StaticResource UriMapper}" />

Monday, 14 December 2009

Model-View-ViewModel (MVVM) pattern

MVVM is gaining considerable traction in the WPF and Silverlight communities. The MVVM pattern can be said to be a specialisation of Fowler’s Presentation Model pattern.

The essence of a Presentation Model is of a fully self-contained class that represents all the data and behavior of the UI window, but without any of the controls used to render that UI on the screen. A view then simply projects the state of the presentation model onto the glass.

There is also some similarity with the Model-View-Presenter (MVP) pattern, with the ViewModel being roughly analogous to the Presenter.  However, unlike MVP the ViewModel doesn’t need a reference to the View – the view uses data binding to be made aware of changes. The ViewModel and not the View performs all modifications made to the model data.

Some features of MVVM:

  • View classes are unaware of Model classes
  • ViewModel and Model classes are unaware View classes (the ViewModel mustn’t assume types of rendering in the View  - e.g. that a button exists)
  • Model classes are unaware of ViewModel and View classes
  • ViewModel classes are aware of Model classes
  • View classes are aware of ViewModel classes

To summarise:

Aware of View Aware of Model Aware of ViewModel
View N/A No Yes
Model No N/A No
ViewModel No Yes N/A

Data binding facilitates loose coupling between the View and the ViewModel. It also supports a standardised input validation model.

The data is typically implemented as properties on the ViewModel. The View consumes that data via data binding. Application logic is typically implemented as methods on the ViewModel that the View can invoke through commanding.

A possible weakness with MVVM in Silverlight applications is the lack of support for Commands.

The following are the differences between Silverlight and WPF regarding commanding:

  • Routed commands are not available in Silverlight. However, the ICommand interface is available in Silverlight, allowing developers to create their own custom commands. The Composite Application Library provides the DelegateCommand and CompositeCommand classes to simplify command implementation. For more information, see the Commands technical concept.
  • In WPF, controls can be hooked up to commands through their Command property. By doing this, developers can declaratively associate controls and commands. This also means a control can interact with a command so that it can invoke the command and have its enabled status automatically updated. Silverlight controls do not currently support the Command property. To help work around this issue, the Composite Application Library provides an attached property-based extensibility mechanism that allows commands and controls to be declaratively associated with each other. For more information, see "Using Commands in Silverlight Commands" in the Commands technical concept.
  • There is no input gesture or input binding support in Silverlight.

http://msdn.microsoft.com/en-us/library/dd458872.aspx

ViewModel classes are easy to test, taking key logic out of the dreaded code behind files.

I need to check out a few things:

See also http://andysonlinenotes.blogspot.com/2010/06/stuff-i-should-be-interested-in.html