Flex and WPF: A comparison – Part 2a

In my earlier post I mentioned that both Flex and WPF do a separation of content from presentation. In the view of keeping the posts short, I am going to split Part 2 of the comparison into two subparts. In this first subpart I will only cover how WPF does the content-style separation. The next post will talk about Flex’s approach.

The WPF way

XAML markup + code behind

        Programming declaratively in XML is definitely more productive than writing plain code in C# or other .Net language. It helps in visualizing the structure of the UI without always relying on a tool. Plus editing and making changes is also easy. XAML or eXtensible Application Markup Language is the new XML based language for creating WPF UIs. One can describe the complete visual hierarchy of the UI in one or more XAML files. In fact it is also possible to add a lot of interactivity directly in XAML. Using data-binding we can connect UI elements together. For example I could connect the output of the Slider control to a Textbox. Complex animations can also be described in XAML using the <Storyboard/> tag and one can also hook up the animations to play when certain events happen – all in XAML. Of course not everything can be done declaratively, so where more fine grained control is needed, one can use the Code Behind class to describe the logic. A WPF application consists of an App.xaml file that describes the Application and a separate startup xaml file that is loaded when the application starts up. Have a look at this App.xaml file.

<Application x:Class=WindowsApplication1.App

xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation

xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml

StartupUri=Window1.xaml>

</Application>

 

Note how I specify the <Application/> and hook it up to the Code behind class using the x:Class attribute. The StartupUri points to Window1.xaml, which is the file that will be loaded when the application starts. Window1.xaml looks something like this:

<Window x:Class=WindowsApplication1.Window1

xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation

xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml

Title=WindowsApplication1

Height=300

Width=300>

</Window>

 

Since we are using the <Window/> tag, the application will create a standard Window control. Our Window is currently empty and has no UI elements and has a code-behind file linked with x:Class attribute. Note that by changing the StartupUri attribute of the <Application/> we can point to a different XAML file.

 

Templates – ControlTemplate, DataTemplate, ItemTemplate

    WPF does the content-style separation using Templates. With templates, it is possible to separate the behavior of the UI control from its presentation / appearance. For example, I could have a <Button/> control that doesn’t look like a Button but still behaves like one. This is possible by changing the default ControlTemplate of the Button to something else. Most UI controls in WPF, except for UserControls and Panels, have a Template property that provides the appearance for that control. The ControlTemplate is responsible for providing not only the appearance but also the behavior, eg. how the button reacts to a mouse-press, mouse-release, mouse-hover. They are specified using Triggers, which describe the appearance when the control is in a certain state.

<ControlTemplate TargetType={x:Type Button}>

<Border

x:Name=Border

CornerRadius=2

BorderThickness=1

Background={StaticResource NormalBrush}

BorderBrush={StaticResource NormalBorderBrush}>

<ContentPresenter

Margin=2

HorizontalAlignment=Center

VerticalAlignment=Center

RecognizesAccessKey=True/>

</Border>

<ControlTemplate.Triggers>

<Trigger Property=IsKeyboardFocusedValue=true>

<Setter TargetName=BorderProperty=BorderBrush

Value={StaticResource DefaultedBorderBrush} />

</Trigger>

<Trigger Property=IsMouseOverValue=true>

<Setter TargetName=BorderProperty=Background

Value={StaticResource DarkBrush} />

</Trigger>

<Trigger Property=IsPressedValue=true>

<Setter TargetName=BorderProperty=Background

Value={StaticResource PressedBrush} />

<Setter TargetName=BorderProperty=BorderBrush

Value={StaticResource PressedBorderBrush} />

</Trigger>

</ControlTemplate.Triggers>

</ControlTemplate>


Similarly we have DataTemplates that describe how a non-UI object should look like, when visual represented. DataTemplates are useful for representing standard CLR objects which are not UI controls. For example I could have a DataTemplate for a Person class that shows the name in a TextBlock and a picture of the Person in an Image.

<DataTemplate TargetType={x:Type model:Person}>

<StackPanel Orientation=Horizontal>

<Image Source={Binding Picture}/>

<TextBlock Text={Binding Name}/>

</StackPanel>

</DataTemplate>

 

Note that I am using the data-binding syntax for binding to the Picture and Name properties of the Person class.

Similar to the DataTemplates are ItemTemplates, which are used in the context of a list control like ListBox, Tree, etc. ItemTemplates describe how each item in a list should appear.

 

Styles, themes for custom controls

    Styles are higher level constructs for describing additional properties of a control in addition to the Template property. Say I have five buttons on my form and I want all of them to be of a particular width (50px). I could do that in a <Style/> tag as follows:

<Style TargetType={x:Type Button}>

<Setter Property=WidthValue=50/>

</Style>

 

Note how I target the Button control using the TargetType attribute. However the above style applies to all Buttons on the form. If you like only specific Buttons to take this style, you can qualify the <Style/> with a x:Key attribute.

<Style x:Key=WidthFiftyStyle TargetType={x:Type Button}>

<Setter Property=WidthValue=50/>

</Style>

 

The Button can refer this style with the Style attribute. The {StaticResource WidthFiftyStyle} syntax is called a MarkupExtension and is used to reference resources.

<Button Style={StaticResource WidthFiftyStyle}>Submit</Button>

 

The standard controls that are available out of the box are useful for most scenarios. However you do want the ability to create your own custom controls. WPF provides you that ability and also gives you a chance to define a default style for your control. Since your custom control will be in a separate .Net assembly, the default style is specified in a generic.xaml file that sits in the /themes folder. When WPF loads your control, it probes into the /themes/generic.xaml file and looks for a style definition for that control (TargetType = your control’s type).

 

Databinding with property change notifications

    Data binding is a great way to do away with a lot of code to keep the UI consistent with the model. Bindings keep your logic clear and easier to maintain. However you do have to take some extra steps and enable your models to participate. In WPF a common way of doing this is to use a ViewModel that wraps the actual Model and also implement the INotifyPropertyChanged interface. The reason we use a wrapper around Model is because we don’t want to pollute the Model class with UI related information.

Inside your ViewModel you have to fire change notifications whenever a property changes, using the PropertyChanged event. This informs WPF that it has to update the corresponding UI element. INotifyPropertyChanged is good for a singular model class. If you have a ListBox control bound to a model-collection, then you need a ViewModel wrapper that extends the ObservableCollection<Model> class. The <> syntax indicates that it is a Generic collection (similar to the C++ templates) for the type: Model. With these extra steps you would have data-bound UI controls that automatically update whenever the model changes.

Custom events – RoutedEvents, Commands

    Most UI paradigms have a mechanism of propagating events raised on controls. Typically these events bubble-up from the child to parent. However WPF makes this propagation strategy customizable with RoutedEvents. All events in WPF are instances of RoutedEvents, which can either follow the Bubbling (bottom-up), Tunneling (top-down) or Direct (only on the element) strategy. Custom UI controls can define their own RoutedEvents.

In addition to RoutedEvents WPF provides a higher level abstraction of Commands. Commands are way of mapping user gestures to actions. The astute reader would have recognized that this nothing but the Command design pattern.

ResourceDictionary

    UI assets like <Style/>, Templates, images, videos etc. are all specified in a ResourceDicionary with a key attribute. In other words, ResourceDictionary is a logical collection of all assets in your application. You can also nest ResourceDictionaries creating a more hierarchical grouping. Typically in a large application you would dedicate a single ResourceDictionary for a particular type of asset. So you might keep all your <Style/>s in a dictionary and DataTemplates in another dictionary. Both of these will then be nested inside a top-level dictionary. The syntax looks something like this:

<ResourceDictionary>

<ResourceDictionary.MergedDictionaries>

<ResourceDictionary Source=Styles.xaml/>

<ResourceDictionary Source=DataTemplates.xaml/>

</ResourceDictionary.MergedDictionaries>

</ResourceDictionary>

 

Note how the nesting is done inside the MergedDictionaries tag.

Packaging into assemblies

    ResourceDictionary is a great way to group related resources together inside an application. However If you want to reuse these dictionaries across many applications, then you would need a higher level abstraction. In .Net you can package all your ResourceDictionaries into an assembly and then reference that assembly inside your application. Packaging your commonly used assets into assemblies will help you create an asset-library for your organization.

 

Summary

    This post has been rather long and touches upon the various building blocks of WPF that enable the content-style separation. You have seen how the appearance and behavior of a UI control can be separated using ControlTemplates. DataTemplates are useful for providing a visual representation for your Model classes. Styles can be used for describing common set of properties for your UI controls. ResourceDictionaries can be used to group assets together and an Assembly can be used to package ResourceDictionaries for reusing across applications.

Databinding is a powerful feature for keeping the UI controls in sync with the model. This is done via property-change notifications. RoutedEvents and Commands can be used to map user gestures to actual business actions.

In the second subpart of this post, we will look at how Flex approaches the problem of content-style separation.

Advertisements

3 Responses to “Flex and WPF: A comparison – Part 2a”

  1. The FlexWinds blog Flex and WPF: A comparison – Part 2b « Says:

    […] and WPF: A comparison – Part 2b February 15th, 2007 — pavanpodila In part-2a we saw some of the building blocks of WPF and how they are used to achieve the content-style […]

  2. WPF vs Flex at Priyanka's Design Booth Says:

    […] How WPF approaches a problem? […]

  3. ارض بالعبور للبيع Says:

    I go to see every day some sites and information sites to read posts,
    however this website presents feature based articles.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: