Showing posts with label WPF. Show all posts
Showing posts with label WPF. Show all posts

Monday, 3 March 2014

Validation adorners not displaying in WPF

The problem

I was developing a WPF application using the IDataErrorInfo interface to perform validation on view models. When errors were encountered I wanted them to be displayed in the UI using adorners to change border appearances and to show error messages. I also wanted these adorners to show when the form first loaded so the user could see straight away what fields needed to be completed.

The problem was that the adorners only appeared after the user changed the values of the validated controls. When the form first loaded things like required fields were not adorned.


Figure 1 – No adorners showing on required fields etc. when the form first loaded.



Figure 2 – The desired result with adorners displayed correctly.

After spending some time checking the behaviour of the application I could see that IDataErrorInfo members were being called when the form loaded and that INotifyPropertyChanged was correctly implemented and the property changed event was being raised correctly.

The solution

The solution was to wrap the form elements in an AdornerDecorator. So, where I previously had a Grid element containing the rows of input controls and labels I wrapped that grid in an AdornerDecorator.

<StackPanel Orientation="Vertical">
    <AdornerDecorator>
        <Grid>
            <Grid.RowDefinitions>
                <!-- Row definitions omitted -->
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <!-- Column definitions omitted -->
            </Grid.ColumnDefinitions>

            <!-- Input controls and labels omitted -->
            
        </Grid>
    </AdornerDecorator>
    
    <!-- Other layout omitted -->
    
</StackPanel>

Explanation

The controls displaying validation errors in the application were based on styles that used the Validation.ErrorTemplate to provide adorned layout to use in the case of errors. For adorners to be displayed there needs to be an AdornerLayer available in the visual tree.

“An Adorner is a custom FrameworkElement that is bound to a UIElement. Adorners are rendered in an AdornerLayer, which is a rendering surface that is always on top of the adorned element or a collection of adorned elements.” [1]

There will be times when there isn’t an AdornerLayer available so you may have to provide one. The way to do this is to add an AdornerDecorator to your XAML remembering that somewhere there will be a call to the static AdornerLayer.GetAdornerLayer method which walks the visual tree looking for an AdornerLayer.

“This static method traverses up the visual tree starting at the specified Visual and returns the first adorner layer found.” [2]
“The AdornerDecorator specifies the position of the AdornerLayer in the visual tree. It is typically used in a ControlTemplate for a control that might host Adorner objects. For example, the ControlTemplate of a Window contains an AdornerDecorator so that the child elements of the window can be adorned. The GetAdornerLayer method returns null if you pass in an element that does not have an AdornerDecorator as an ancestor in its visual tree.” [3]

Note that - as stated above - the AdornerDecorator is typically used in a ControlTemplate. You might want to explore this avenue further.

References

[1] Adorners Overview
[2] AdornerLayer.GetAdornerLayer Method
[3] AdornerDecorator Class

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).

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, 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

Monday, 16 November 2009

Commands in WPF

The GoF Command design pattern is defined as  "encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations". WPF Commands provide methods for decoupling UI events, the handling of these events and the registration of UI elements interested in handling the events.

WPF Commands are really very much like events but they offer some advantages:

  • Reuse – Commands can be registered with multiple controls allowing for reuse.
  • Routing – Commands based on the RoutedCommand base class can participate in event bubbling.
  • XAML integration – Commands can be defined and registered with controls in XAML.
  • Input gestures – There are a stack of build-in commands which are already configured to handle input gestures (e.g. using ApplicationCommands.Paste, a RoutedUICommand, will give you all Ctrl-V etc. out of the box).
  • Testability – Commands can be tested.
  • Localisation – Commands can be localised (which is done for you with built-in commands).

All WPF commands must implement a simple interface, ICommand:

public interface ICommand
{
    // Methods.
    void Execute(object parameter);
    bool CanExecute(object parameter);

    // Events.
    event EventHandler CanExecuteChanged;
}
  • Execute - contains the logic to perform the action that makes up the command
  • CanExecute - returns a value that determines if the command is currently valid
  • CanExecuteChanged event - raised when the value returned by the CanExecute method has changed

Built-in commands take advantage of CanExecute and CanExecuteChanged to enable/disable functionality for you (i.e. registered controls’ will automatically become enabled/disabled appropriately).

See http://www.microsoft.com/belux/msdn/nl/community/columns/jdruyts/wpf_commandpattern.mspx

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

More to follow on this one…

Monday, 16 November 2009

Sunday, 8 November 2009

Dependency Properties

Dependency properties are one of the features that allow for extension in WPF.

“Windows Presentation Foundation (WPF) provides a set of services that can be used to extend the functionality of a common language runtime (CLR) property. Collectively, these services are typically referred to as the WPF property system. A property that is backed by the WPF property system is known as a dependency property.”

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

The value of a normal .NET property is read or written directly from or to a field in a class. The value of a DependencyProperty is read or written by calling GetValue() or SetValue() inherited from the DependencyObject base class.

Values are not stored in a field but in a dictionary provided by DependencyObject. The key is the name of the property and the value is the value you want to set.

The advantages of dependency properties include:

  • Change notification
    • Dependency properties have a built-in change notification mechanism so by registering a callback in the property metadata you get notified when the value of the property has been changed. Actions can be triggered in response to this notification like:
      • re-rendering appropriate elements,
      • updating the layout,
      • refreshing data-binding etc.
      • Look-up property triggers.
  • Property value inheritance
    • The value of a dependency property is resolved by using a value resolution strategy (i.e. flowing values down the element tree). But:
      • Not every dependency property participates in property value inheritance.
      • There may be other high-priority sources setting the property value.
  • Support for multiple providers
    • Property value providers can independently attempt to set the value of a dependency property. To avoid chaos there i a defined value resolution strategy.
  • Reduced memory footprint
    • The default values are stored once within the dependency property.

See http://wpftutorial.net/DependencyProperties.html

Sunday, 8 November 2009

Friday, 6 November 2009

XAML markup extensions

“Markup extensions are a XAML concept. In attribute syntax, curly braces ({ and }) indicate a markup extension usage. This usage directs the XAML processing to escape from the general treatment of attribute values as either a literal string or a directly string-convertible value.” (my italics)

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

“When used to provide an attribute value, the syntax that distinguishes a markup extension to a XAML processor is the presence of the opening and closing curly braces ({ and }). The type of markup extension is then identified by the string token immediately following the opening curly brace.

When used in property element syntax, a markup extension is visually the same as any other element used to provide a property element value: a XAML element declaration that references the markup extension class as an element, enclosed within angle brackets (<>). ”

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

XAML-defined markup extensions

There are a number of XAML extensions not specific to WPF. These are usually identified by the prefix x: which is an XML prefix used to map the XAML namespace.

Extension tag Description
x:Type Supplies the Type object for the named type. This is used most frequently in styles and templates.
x:Static Produces static values from value-type code entities that are not directly the type of a property's value, but can be evaluated to that type.
x:Null Specifies null as a value for a XAML property.
x:Array Provides support for creation of general arrays in XAML syntax, for cases where the collection support provided by base elements and control models is deliberately not used.

Nested extension syntax

Extensions can be nested. For example:

<Setter Property="Background"  Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />

{} Escape Sequence / Markup Extension

To escape curly braces precede with the {} escape sequence, especially where the first character of the property is an opening curly brace. For example:

<Setter Property="SomeProperty"  Value="{}{" />

The value of SomeProperty will be set to {.

“The {} escape sequence is frequently required when specifying an XML type that must include a namespace qualifier in a location where XAML markup extension might appear. This includes the beginning of an XAML attribute value, and within a markup extension, immediately after an equal-sign. The following example shows escapes for an XML namespace that appears at the beginning of a XAML attribute value.”

  <StackPanel.Resources>
    <DataTemplate DataType="{}{http://planetsNS}Planet" >
      <StackPanel Orientation="Horizontal">
        <TextBlock Width="100" Text="{Binding Path=Element[{http://planetsNS}DiameterKM].Value}" />
        <TextBlock Width="100" Text="{Binding Path=Attribute[Name].Value}" />
        <TextBlock Text="{Binding Path=Element[{http://planetsNS}Details].Value}" /> 
      </StackPanel>
    </DataTemplate>
  </StackPanel.Resources>

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