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:

Monday, 28 June 2010

Using Commands in Silverlight

Commands in Silverlight are a valuable way of getting away from the code-behind, event handler trap and keeping the UI decoupled from application logic. When used in combination with the MVVM pattern, what would have been event handlers are now effectively properties on the ViewModel (properties that return an object that implements ICommand), bound to the Command property of UI elements such as buttons.
Note: The command approach works well for instances where a UI element is clicked (e.g. buttons) so the resulting code (the command) is executed once. In cases where values are constantly changing (e.g. the value of a slider control) the command approach falls down; you can’t attach a command to a UI element event handler. For such event-driven scenarios you need to use a different approaches: use behaviours, bind the changing value to a property in the ViewModel that in turn updates other bound properties when changed, or create user controls and create dependency properties for the changing values which are bound via the ViewModel.
See http://thejoyofcode.com/Animating_when_Data_Changes_Part_II.aspx.
Before going further be aware that Prism (the Composite Application Library) already has some support for commanding. The Composite Application Library provides the DelegateCommand and CompositeCommand classes to simplify command implementation.
See the Commands technical overview: http://msdn.microsoft.com/en-us/library/dd458928.aspx
A DelegateCommand implementation might look something like this:
public class DelegateCommand : ICommand { private Func<object, bool> _canExecuteFunc;
    private Action<object> _executeAction;
    private bool _canExecute;
    public event EventHandler CanExecuteChanged;

    public DelegateCommand(Action<object> executeAction, Func<object, bool> canExecuteFunc)
    {
        _executeAction = executeAction;
        _canExecuteFunc = canExecuteFunc;
    }

    public bool CanExecute(object parameter)
    {
        bool temp = _canExecuteFunc(parameter);
        if (_canExecute != temp)
        {
            _canExecute = temp;
            if (CanExecuteChanged != null)
            {
                CanExecuteChanged(this, new EventArgs());
            }
        }
        return _canExecute;
    }
  
    public void Execute(object parameter)
    {
        _executeAction(parameter);
    }
}
To use a DelegateCommand you then need to define a command property on the view model:
public ICommand MyCommand { get; set; }
and then instantiate a DelegateCommand passing in the appropriate methods for CanExecute and Execute:
LoadProductsCommand = new DelegateCommand(MyMethod, CanExecuteMyMethod);
The DelegateCommand can be bound to a UI control:
<Button Content="Push Me" Command="{Binding MyCommand}" />
It is possible to pass parameters to the command:
<Button Content="Push Me" Command="{Binding MyCommand}" CommandParameter="{Binding ElementName=SomeUiEelement, Path=Text}" />
Monday, 28 June 2010

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

Design resources for application development

I thought it was time to keep track of some interesting resources relevant to interface design.

Blogs

UX and UI Patterns

Windows Phone 7

Books

  • The Elements of Graphic Design (ISBN 1581152507)
  • How to Think Like a Great Graphic Designer (ISBN 1581154968)
  • The Elements of Typographic Style (ISBN 0881792063)
  • The Internet: A Writer’s Guide (ISBN 071365192X)

Inspiration

  • Typography Now Two (ISBN 186154023X)
  • Website Graphics Now (ISBN 050028119X) – old but still fun.
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>

Friday, 11 June 2010

Sizing elements in Silverlight

I keep having to remind myself about sizing in Silverlight but it’s easy really:

Sizing Type Description Usage
Absolute Choose the exact size in pixels. Changing the container size has no effect. Width=”100”
Automatic Element is given the exact amount of space it needs and no more. Width=”Auto”
Proportional Space is divided between elements in a group (e.g. rows in a Grid). A number can be given to proportionally assign space. Width=”*”
Width=”2*”

For example:

<Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
        <RowDefinition Height="0.25*" />
        <RowDefinition Height="1.5*" />
        <RowDefinition Height="1*" />
    </Grid.RowDefinitions>
</Grid>
Friday, 11 June 2010