Prism Navigation – ViewModel first

Navigating to view using prism navigation service is straight forward and there are lot of examples on web around this.With MVVM i always found ViewModel first approach as best because of lot of reasons, some of them are

  • With MVVM, ViewModels is your application
  • No threading issues as you will always create view models which can be created on any thread.
  • More responsive , you are not dealing with dispatcher context to create views and let WPF system decide when to create views.
  • No Memory leaks, The life cycle of views is controlled by WPF system in most efficient way
  • More testable application, Since you app lives in view models and they don’t have UI beasts,
  • And lot more..

This post cover a small trick to implement the ViewModel first navigation using Prism 5.0 for WPF.

1. What ever IoC you are using (the code is based on StructuralMap) expose the RegisterForNavigation<T> method and from module initialization, register interface of viewModels participating in navigation process. The RegisterForNavigation<T> will look like

public static void RegisterTypeForNavigation<T>(this ConfigurationExpression reg)
{
reg.For<object>().Use(() => ServiceLocator.Current.GetInstance(typeof(T)))
.Named(typeof(T).FullName);
}

And some where in module initialization you call this method

configurationExpression
.RegisterTypeForNavigation<ICustomerDetailViewModel>();

And to navigate to this view model just use

var parameters = new NavigationParameters { { "Activity", SelectedActivity }, { "ColumnName", columnName } };
var uri = new Uri(typeof(ICustomerDetailViewModel).FullName, UriKind.RelativeOrAbsolute);
regionManager.RequestNavigate(ShellRegions.Workspace, uri, parameters);

And obviously some where in you data template definition there should a (DataTemplate) mapping which WPF uses to swap the view model with corresponding view (and set data context too)..

Attached Behaviors Memory Leaks

“Behavior is the base class for providing attachable state and commands to an object. The types the Behavior can be attached to can be controlled by the generic parameter. Override OnAttached() and OnDetaching() methods to hook and unhook any necessary handlers from the AssociatedObject.”
If you using of the behaviors or trigger actions and these subscribe internally on events you’re in trouble. The memory used by them is never released. And could held lot of objects including views in memory causing memory leaks.

“When you subscribe to an event the event source ends up with a hard reference to the event handler. This creates a situation where the event handler cannot be cleaned up as long as the event source exists.”
So to unhook events you probably write code in OnDetaching methods however a behavior might not detach when you expect it to and vice versa, leaving added event handler on the control to survive GC. OnDetaching is only called when you explicitly remove behaviour.
The solution:
The OnAttached is called when XAML parser parses XAML and creates instance of behaviour and adds this to BehaviorCollection of target control which is exposed as DependencyAttached property. However when view is disposed, the collection (Behavior collection) was disposed of, it will never trigger OnDetaching method. If the behaviour is not properly cleanup it will not be collected by GC and will also hold BehaviorCollection and other behaviors in that collection. The behaviours are designed to extend AssociatedObject, as long as you are subscribing to AssociatedObject events its fine as the AssociatedObject (publisher) will die and your behaviour will be collected by garbage collector.

Use BehaviorBase (see code below) to avoid memory leak from behaviours. The same technique can also be used for triggers.
Drive all your behaviors from BehaviorBase class and override OnSetup and OnCleanup methods. OnSetup is triggered when behaviour explicitly is attached to already loaded object at runtime or when object is loaded.
BehaviorBase

 
public abstract class BehaviorBase<T> : Behavior<T> where T : FrameworkElement
{
private bool _isSetup = true;
private bool _isHookedUp;
private WeakReference _weakTarget;

protected virtual void OnSetup() {}
protected virtual void OnCleanup() {}
protected override void OnChanged()
{
       var target = AssociatedObject;
       if (target != null)
       {
              HookupBehavior(target);
       }
       else
       {
              UnHookupBehavior();
       }
}

private void OnTarget_Loaded(object sender, RoutedEventArgs e) { SetupBehavior(); }

private void OnTarget_Unloaded(object sender, RoutedEventArgs e) { CleanupBehavior(); }

private void HookupBehavior(T target)
{
       if (_isHookedUp) return;
       _weakTarget = new WeakReference(target);
       _isHookedUp = true;
       target.Unloaded += OnTarget_Unloaded;
       target.Loaded += OnTarget_Loaded;
       SetupBehavior();
}

private void UnHookupBehavior()
{
       if (!_isHookedUp) return;
       _isHookedUp = false;
       var target = AssociatedObject ?? (T)_weakTarget.Target;
       if (target != null)
       {
              target.Unloaded -= OnTarget_Unloaded;
              target.Loaded -= OnTarget_Loaded;
       }
       CleanupBehavior();
}

private void SetupBehavior()
{
       if (_isSetup) return;
       _isSetup = true;
       OnSetup();
 }

private void CleanupBehavior()
{
       if (!_isSetup) return;
       _isSetup = false;
       OnCleanup();
}
}

ComplexLayout

WPF/Silverlight – Complex Layout -Simple solution

Will write soon on this..

Binding to XML WPF supports binding directly to XML objects, as demonstrate in this article.Like the ObjectDataProvider, the XmlDataProvider allows simple XAML based declaration of XML resources for use in your WPF application. – For details check source code.. Here is the source code (Vs2010) : Download

Button XAML

XAML Button’s in 5 mins..

XAML

<Grid x:Name="LayoutRoot" Background="#FF54126A">
 <Grid  Height="87" Width="400" Margin="31,85.5,209,0" VerticalAlignment="Top" d:LayoutOverrides="Height" >
 <Border Background="#FF449712" Margin="1"   CornerRadius="5" BorderThickness="1">
 <Border.BorderBrush>
 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
 <GradientStop Color="#6D000000" Offset="0"/>
 <GradientStop Color="Black" Offset="0.994"/>
 </LinearGradientBrush>
 </Border.BorderBrush>
 <Border.Effect>
 <BlurEffect Radius="2"/>
 </Border.Effect>
 </Border>
 <Border   CornerRadius="5" Margin="3" BorderThickness="0,2,0,0">
 <Border.Effect>
 <BlurEffect Radius="3"/>
 </Border.Effect>
 <Border.BorderBrush>
 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
 <GradientStop Color="#00000000" Offset="1"/>
 <GradientStop Color="#D7FFFFFF"/>
 </LinearGradientBrush>
 </Border.BorderBrush>
 <Border.Background>
 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
 <GradientStop Color="#1DB1B1B1" Offset="0.5"/>
 <GradientStop Offset="0.5"/>
 </LinearGradientBrush>
 </Border.Background>
 </Border>
 <TextBlock Text="Buy Now !" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontSize="40"  FontFamily="Segoe UI Symbol">
 <TextBlock.Effect>
 <DropShadowEffect BlurRadius="10" ShadowDepth="0"/>
 </TextBlock.Effect>
 </TextBlock>
 </Grid>

 <Grid  Height="87" Width="400" Margin="32,209.5,208,183.5" >

 <Border Background="#FF0C64CA" Margin="1"   CornerRadius="5" BorderThickness="1">
 <Border.BorderBrush>
 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
 <GradientStop Color="#6D000000" Offset="0"/>
 <GradientStop Color="Black" Offset="0.994"/>
 </LinearGradientBrush>
 </Border.BorderBrush>
 <Border.Effect>
 <BlurEffect Radius="2"/>
 </Border.Effect>
 </Border>
 <Border   CornerRadius="5" Margin="3" BorderThickness="0,2,0,0">
 <Border.Effect>
 <BlurEffect Radius="2"/>
 </Border.Effect>
 <Border.BorderBrush>
 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
 <GradientStop Color="#00000000" Offset="1"/>
 <GradientStop Color="#D7FFFFFF"/>
 </LinearGradientBrush>
 </Border.BorderBrush>
 <Border.Background>
 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
 <GradientStop Color="#1DB1B1B1" Offset="0.5"/>
 <GradientStop Offset="0.5"/>
 </LinearGradientBrush>
 </Border.Background>
 </Border>
 <TextBlock Text="Download Trial !" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontSize="40"  FontFamily="Segoe UI Symbol">
 <TextBlock.Effect>
 <DropShadowEffect BlurRadius="10" ShadowDepth="0"/>
 </TextBlock.Effect>
 </TextBlock>
 </Grid>

 </Grid>

Reactive Extensions (Rx) Data Streaming

You have probably heard about Reactive Extensions, a library from Microsoft that greatly simplifies working with asynchronous data streams and allows to query them with LINQ operators.In my previous post I briefly discussed about loading data via entity framework asynchronously however it lacks getting chunks of data. This post demonstrates how to use Reactive Extensions for loading data from database asynchronously in chunks covering brief around Reactive extension library.

Reactive extensions (Rx)
The Reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators. Using Rx, developers represent asynchronous data streams with Observables, query asynchronous data streams using LINQ operators, and parameterize the concurrency in the asynchronous data streams using Schedulers. Simply put, Rx = Observables + LINQ + Schedulers.Data sequences can take many forms, such as a stream of data from a file or web service, web services requests, system notifications, or a series of events such as user input. Reactive Extensions represents all these data sequences as observable sequences. An application can subscribe to these observable sequences to receive asynchronous notifications as new data arrive. The Rx library is available for desktop application development in .NET. It is also released for Silverlight, Windows Phone 7 and JavaScript.

Reactive programming allows you to turn those aspects of your code that are currently imperative into something much more event-driven and flexible.Reactive programming can be applied to a range of situations—from WPF applications to Windows Phone apps—to improve coding efficiency and boost performance.

Code snippets to asynchronous load data via entity framework in batches of 200 records.

public void LoadPostCodes()
{
 btnStatus.Content = "Started";
 listBox1.Items.Clear();
 (from p in cx.MAS_PostCode select p)
 .ToObservable(Scheduler.NewThread)
 .Buffer(200)
 .ObserveOn(SynchronizationContext.Current)
 .Subscribe(ld =>
 {
 foreach (var item in ld)
 {
 ListBoxItem litem = new ListBoxItem();
 litem.Content = string.Format("{0} {1}", item.PC_PostCode, item.PC_Address1);
 listBox1.Items.Add(litem);
 listBox1.ScrollIntoView(litem);
 }
 button1.Content = listBox1.Items.Count.ToString();
 },
 () => { btnStatus.Content = "Finished"; }
 );
}

Have finished writing MVVM(Nano View model) based scenario & Rx implementations …

Will write soon and publish code..

Regards
Rajnish