Monday, January 28, 2013

Windows Store Apps with F# (part 3) : Data Binding and MVVM

In this series of posts we investigate the interoperability between WinRT and F#. In the previous post we solved some issues by adding input checking and async event handling. Our code still contained C# code. We can ride of some of the C# code by data binding.
Data binding connects XAML code directly with .NET objects. Let’s create a simple example.
Open the project we have created in part 1 and updated in part 2 and add a F# file called Process. We add the namespace MathLib and create an object Process.
namespace MathLib
type Process() =
let mutable _output = "output"

member x.Output
with get() = _output
and set(v) =
_output <- v

and rebuild the project so the Process object becomes available in the C# project.

To the C# code of the MainPage we add a process variable, create a new Process object. We add it to the DataContext of the MainPage:
Process process;
public MainPage()
{
this.InitializeComponent();
process =
new Process();
this.DataContext = process;
}

and change the MainPage.xaml: Text="{Binding Output}"
<TextBlock Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3"  
x:Name="result"
Style="{StaticResource FSharp}"
Text="{Binding Output}"
/>

F5 and this is the result.

screenshot_01262013_142046

The initial value of the Process object (“output”) is shown at the location of the result TextBlock.

Next we at an extra property to Process object.
namespace MathLib
type Process() =
let mutable _input = "input"
let mutable _output = "output"

member x.Input
with get() = _input
and set(v) =
_input <- v

member x.Output
with get() = _output
and set(v) =
_output <- v

And add a Execute method.
     member x.Execute() = 
x.Output <- _input |> MathLib.Wrapper.IsPrimeText

And change the XAML of the TextBox
<TextBox Grid.Row="1" Grid.Column="3"                  
x:Name="inputValue"
FontFamily="Verdana"
FontSize="32"
Text="{Binding Path=Input, Mode=TwoWay}"
/>

We change the code of the event handler:
private void OnClick(object sender, RoutedEventArgs e)
{
process.Execute();
result.Text = process.Output;
}

and test the result by entering “12” as input and click the button.

screenshot_01262013_151226

So by adding “Mode=TwoWay” the input value of the TextBox is transferred back to the Input property of the Process object.

Let’s change the event handler, let’s remove the last line:
private void OnClick(object sender, RoutedEventArgs e)
{
process.Execute();
}

and test again.

screenshot_01262013_151435

This time the result is not updated. We have to notify the XAML that things have changed.

We can tell the XAML that things have changed by implementing the INotifyPropertyChanged interface. This is a simple interface, it has one method: PropertyChanged.

We could write this code ourselves, or we could leverage what is already available (standing on the shoulders of giants). So let’s enter MVVM (Model View ViewModel).

There are several related architectural patterns MVP, MVC, MVVM. They all prescribe the way separation of concerns is implemented a rich user interface application.

So the main theme is separation of concerns. In the case of MVVM we have:




  • Model. This is all the code that does not care about the presentation. It contains all code that is unaware of users interacting with the system, so we could create several ways of presenting the model to the user: WPF, Windows Store App, internet website, etc., in all cases the model stays the same. So the model could contain:



    • all business logic

    • all persistence related logic

    In our example the model is managed by a mathematician. He is the domain expert and knows everything about primes.


  • View. This is the presentation layer. It describes the look and feel of the application. The aim is to create declarative code like XAML and reduce the code in the code behind as much as possible.
    In our example the view is managed by a UI designer. He has chosen  the red color and the font.


  • View Model. This is the bridge between the model and view. Imaging the model and view are already available. We know what it the App looks like and all business and persistence logic is created. All code required to make the application complete will be part of the View Model.

This is where we are right know in our example. To complete the application we have to create View Model code. We could write this code ourselves, or we could leverage what is already available.

There are several MVVM frame works available: MVVVM Frameworks.

Of course we go for the F# option: FSharpWpfMvvmTemplate by Dan Mohl. This template was not created with WinRT in mind, so we have to be careful.

Create a new base class in the F# project called “ViewModelBase.fs” and copy the code for the template project:
//https://github.com/dmohl/FSharpWpfMvvmTemplate
namespace FSharpWpfMvvmTemplate.ViewModel
open Systemopen System.Windowsopen System.Windows.Inputopen System.ComponentModel
type ViewModelBase() =
let propertyChangedEvent = new DelegateEvent<PropertyChangedEventHandler>()
interface INotifyPropertyChanged with
[<CLIEvent>]
member x.PropertyChanged = propertyChangedEvent.Publish
member x.OnPropertyChanged propertyName =
propertyChangedEvent.Trigger([| x;
new PropertyChangedEventArgs(propertyName) |])

And change the code of the Process class:
namespace MathLib
open FSharpWpfMvvmTemplate.ViewModel
type Process() =
inherit ViewModelBase()
let mutable _input = "input"
let mutable _output = "output"

member x.Input
with get() = _input
and set(v) =
_input <- v
x.OnPropertyChanged(
"Input")

member x.Output
with get() = _output
and set(v) =
_output <- v
x.OnPropertyChanged(
"Output")

member x.Execute() =
x.Output <- MathLib.Wrapper.IsPrimeText _input

we derive the Process class from the ViewModelBase class and raise the OnPropertyChanged event when the value of one of the properties is changed.

ProcessUp

We have to move the Process file to it’s correct place in the project to let it compile:

ProcessDown

The result:

screenshot_01272013_115544

So it works. We have now two issues to solve:




  1. The code we created can not deal with log running calculations. Just enter 756771235126757131 and the UI freezes.

  2. We still have an event handler, the button click. Is there a better way to deal with this so we can write the what happen after we click the button with F# code?

We solve the second issue first. Again MVVM comes to the rescue. We can bind a Command to the button. A Command is a class that implements the ICommand interface. We copy again from FSharpWpfMvvmTemplate. Create a new F# file and call it RelayCommand and copy the code:
//https://github.com/dmohl/FSharpWpfMvvmTemplatenamespace FSharpWpfMvvmTemplate.ViewModel
open Systemopen System.Windowsopen System.Windows.Inputopen System.ComponentModel
type RelayCommand (canExecute:(obj -> bool), action:(obj -> unit)) =
let event = new DelegateEvent<EventHandler>()
interface ICommand with
[<CLIEvent>]
member x.CanExecuteChanged = event.Publish
member x.CanExecute arg = canExecute(arg)
member x.Execute arg = action(arg)

Replace the Execute method Process file by the ExecuteCommand:
     member x.ExcecuteCommand = 
new RelayCommand ((fun canExecute -> true),
(
fun action ->
x.Output <- x.Input |> Wrapper.IsPrimeText ))

Remove the event handler in the code behind and change the XAML of the button into:
<Button Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" 
Content="Is it a prime?"
x:Name="calculate"
HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="#FFE68484" FontFamily="Verdana" FontSize="32"
Command="{Binding ExcecuteCommand}"/>

We deleted the Click handler and add the binding of the Command.

F5 and the app works the way it worked, this time without the C# event handler and with F# Command.

To solve the first issue, dealing with long running calculations we change the code of the Command:
     member x.ExcecuteCommand = 
new RelayCommand ((fun canExecute -> true),
(
fun action ->
let
task = x.Input |> Wrapper.IsPrimeTask
x.Output <- task.Result))

in this case task wrapper to perform the code asynchronous.

So everything works fine again.

screenshot_01282013_091535

Let’s end with two remarks, the first is related with MVVM, the second with F# async.

From our solution it is not clear how we dealt with separation of concerns.

In our case we have a very small model, it contains just the IsPrime function. The View is the C# project and so the remaining F# code has to be the View Model: the wrappers, the Process class, the ViewModelBase and the RelayCommand are all part of the glue we needed to make the IsPrime function available for the user interface. In a real world project we have to make the structure explicate.

In stead of using a Task we could use the F# async workflow. So let’s replace the ExecuteCommand by
     member x.ExcecuteCommand = 
new RelayCommand ((fun canExecute -> true),
(
fun action ->
let
execute =
async {
x.Output <-Wrapper.IsPrimeText(x.Input)
}
execute |> Async.Start
))

F5 and enter a value un the TextBox. We get an exception:

Exeption

The Dutch inner exception message tell us that we used the wrong thread to update the UI.

We can fix this changing the ViewModelBase. We capture the context at initialization and Post at the context.
type ViewModelBase() =
//capture the context of the UI
let context = System.Threading.SynchronizationContext.Current
let propertyChangedEvent = new DelegateEvent<PropertyChangedEventHandler>()
interface INotifyPropertyChanged with
[<CLIEvent>]
member x.PropertyChanged = propertyChangedEvent.Publish
member x.OnPropertyChanged propertyName =
//Post at the right thread
context.Post(( fun _ -> propertyChangedEvent.Trigger([| x; new PropertyChangedEventArgs(propertyName) |])), null)

After the fix everything works fine again.

The next post we discuss dealing with collections from a XAML F# perspective.

Thursday, January 24, 2013

Windows Store Apps with F# (part 2) : async/await


In my last post we created an windows apps and discussed the F# and C#/XAML interoperability. We discovered two issue:
  1. Long running calculations made the UI frees.
  2. The improper handling of the input made the app crash.
The way we deal with issues is an architectural decision. One can choose to have a slim F# library. The only responsibility is to handle the business logic, nothing else. In our case this is a math library. There is nothing wrong with decision, the other concerns are handled at the C#/XAML site by C# developers and XAML designers. We could resolve the first issue by wrapping the calculation in a task and await it. We could solve the input issues by writing a handler that will handle TextBox TextChanged  event.
If this is your decision the post ends here.
Or we could decide to minimize the C# code and solve all issues at the F# site. That is the way we will continue.
We start by where we left last time.
We first fix the second issue.
We delete in the MainPage XAML the last two TextBlocks and add a new one:
<TextBlock Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3"  x:Name="result" Style="{StaticResource FSharp}" />

and add a text wrapper function to a new F# file called Wrapper.
module MathLib.Wrapper
open System
let IsPrimeText text =
let success, number = Int64.TryParse(text)
if success then
if
Prime.IsPrime number then
number.ToString() + " is a prime number"
else
number.ToString() + " is not a prime number"
else
text + " is not a valid number"

Now we can change the OnClick event handler in
private void OnClick(object sender, RoutedEventArgs e)
{
result.Text =
Wrapper.IsPrimeText(inputValue.Text);
}

All the code to handle the text input and displaying the result are now in the wrapper. Text input does not crash the app.

screenshot_01242013_115705

In a real project we could put more logic to del with input in the wrapper functions.

Next we have to deal with long running calculations. The new C# way is to use async/await. so we add async to the OnClick handler. We get a warning.

Warning
The warning tells us that we need to await something, and this should be a Task.

So we create a second F# wrapper:
open System.Threading.Tasks
let IsPrimeTask text =
Task<string>.Factory.StartNew(
fun _ -> IsPrimeText text)

And call this function with await:
private async void OnClick(object sender, RoutedEventArgs e)
{
result.Text =
"start";
result.Text =
await Wrapper.IsPrimeTask(inputValue.Text);
}

When we start the application and check 756771235126757131.

screenshot_01242013_121614

The task is started and we can still update the UI. So the issues are solved.

Remark: This works because it is .NET interoperability. One should use the WinRT the  interface  IAsyncOperation<string>.
private async void OnClick(object sender, RoutedEventArgs e)
{
result.Text =
"start";
IAsyncOperation<string> operation = Wrapper.IsPrimeTask(inputValue.Text).AsAsyncOperation<string>();

result.Text =
await operation;
}

This interface does not seem to be available in the F# library. Fortunately we can not reference a F# Portable Library in a JavaScript App:

Html_FSharp

So this is not an issue at the moment.

Next time we will look for ways to get ride op the event handling code by looking at data binding and MVVM.

Wednesday, January 23, 2013

Windows Store Apps with F# (part 1) : Make things as simple as possible, but not simpler.


During the initial phase of the Windows 8 beta period it was not possible to integrate F# code in a Windows 8 store app. After the final release of Visual Studio 2012 it is possible to create hybrid projects. In this series of posts I want to show you some of the projects I use to experiment with F# and Windows App Store integration.
I will focus on the interoperability and assume that you are able to find resources to learn the details of XAML, Windows 8 store apps and F#.

In the first example we create a simple solution and just add some F# code.
The F# code will determine if a number is a prime number. The App UI should have a text box to enter a value, a button to start the check and a text block to display the result.
We start by creating a blank windows store app:
CreateProject
Open the created main page
MainPage
and start designing the layout of the page.
    <Page.Resources>
<
Style x:Key="FSharp" TargetType="TextBlock" BasedOn="{StaticResource BasicTextStyle}">
<
Setter Property="FontFamily" Value="Verdana"/>
<
Setter Property="FontSize" Value="32"/>
</
Style>
</
Page.Resources>

Next we change the color of the grid and add some columns and rows:
 <Grid Background="#FF8F0A0A">
<
Grid.ColumnDefinitions>
<
ColumnDefinition Width="10*"/>
<
ColumnDefinition Width="200"/>
<
ColumnDefinition Width="100"/>
<
ColumnDefinition Width="300"/>
<
ColumnDefinition Width="20*"/>
</
Grid.ColumnDefinitions>
<
Grid.RowDefinitions>
<
RowDefinition Height="10*"/>
<
RowDefinition Height="50"/>
<
RowDefinition Height="100"/>
<
RowDefinition Height="50"/>
<
RowDefinition Height="20*"/>
</
Grid.RowDefinitions>

And finally add the controls to the grid:

  <TextBlock Grid.Row="1" Grid.Column="1"
Text="Input value:"
Style="{StaticResource FSharp}"/>

<
TextBox Grid.Row="1" Grid.Column="3"
x:Name="inputValue"
FontFamily="Verdana" FontSize="32" />

<
Button Grid.Row="2" Grid.Column="1"
Grid.ColumnSpan="3"
Content="Is it a prime?" x:Name="calculate"
HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="#FFE68484"
FontFamily="Verdana" FontSize="32"/>

<
TextBlock Grid.Row="3" Grid.Column="1"
Text="Result:"
Style="{StaticResource FSharp}"/>

<
TextBlock Grid.Row="3" Grid.Column="3"
x:Name="result"
Style="{StaticResource FSharp}" />



This is page in de designer:



Designer

Now is time to add the F# code. We add an F# Portable Library call “MathLib” to the solution.

FSharpProject


Rename PortableLibrary1 to Lib and delete the Script file.

FSharpProject2

And add the F# code to the Lib file:
module MathLib.Prime
let IsPrime n =
if n < 2L then
false
else
seq
{ 2L .. n - 1L}
|> Seq.exists(
fun x -> n % x = 0L)
|> not

This is not the most sophisticated prime check but it will do for our projects.

We have created a module we can use MathLib is the namespace, Prime is a static class and IsPrime is a static function.

The code i in line with the definition of a prime number: A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.

Now we have to create interoperability. We add a reference to the MathLib project:

AddReference

and build the solution. This will make the meta data of the MathLib project available for the  WinRTFSharpSimple project.

Next we create add a button click event:
 <Button Grid.Row="2" Grid.Column="1"
Grid.ColumnSpan="3"
Content="Is it a prime?" x:Name="calculate"
HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="#FFE68484"
FontFamily="Verdana" FontSize="32" Click="OnClick"/>

and add an handler at the code behind:

private voidOnClick(objectsender,RoutedEventArgs e)
{
    result.Text =
Prime.IsPrime(Convert.ToInt64(inputValue.Text)).ToString();
}


and add a namespace:

OnClick

Time to test the app, F5:

screenshot_01232013_200741

screenshot_01232013_200947

This looks fine.

In case we enter 756771235126757131

screenshot_01232013_201358

the app freezes and we can not interact with the app (issue 1).

In case we enter “abc” the app crashes (issue 2).

How could we solve these issues?

We can fix them at the C# site or we could fix the at F# site, both are possible. In the next post I will discuss a solution at the F# site.

Monday, January 30, 2012

Dutch article: Monads voor de .NET-ontwikkelaar is available at the SDN site

I have written an article for the Dutch developer magazine of SDN (Magazine 111). It is titled: “Monads voor de .NET-ontwikkelaar”. It is now on line: http://www.sdn.nl/SDN/Artikelen/tabid/58/view/View/ArticleID/3206/Monads-voor-de-NET-ontwikkelaar.aspx.

I have tried to read the English version by Google translate. This is not a very good translation. I do not recommend to read it this translation. The German version is even worse. It contains Engels words that are not part of the Dutch version.

Tuesday, October 4, 2011

BCL Team Blog provides more information on code reuse (Portable Libraries part 4)

Today the BCL Team Blog addressed the issue of code reuse: Porting existing .NET code to Metro style apps

"One of the things we know people want to do is reuse existing .NET code but due to the constraints on Metro style apps it is not possible to directly reuse existing .NET class libraries nor is it always possible to simply recompile existing code. We realize this is going to be a pain point for many current .NET developers so we are working on a guide at the .NET for Metro style apps overview page which will assist developers in translating their existing .NET skill set into the Metro style apps world.”

Bringing existing managed code into Metro style apps" by Daniel Plaisted is a recommended resource.

Daniel ports a windows phone app to a Metro app. Most of presentation is mainly about porting the UI.

Some slides from the presentation:

move_code

differenes

Getting the pictures from a local folder.

folders

There is no database access.

Wednesday, September 28, 2011

.NET portability is not an afterthought (adding another layer of indirection - Portable Libraries part 3)

Before //build/ I was not aware of the Portable Class Libraries Project. The origin of the project is the notion that the number of platform that provide .NET support has increased from one to four and that this number will increase in the future. Making .NET available on more platforms is the future of .NET.

The Portable Class Libraries Project was the first attempt of solving the portability issue but it ran into some constraints. One of them was the increasing complexity: “Portability is an afterthought”.

After watching some of the presentation at //build/ and experimenting with Visual Studio Express for Windows Developer Preview I thought that the whole purpose of creating a portable library was to bridge the gap between .NET and the WinRT.

ClassLibrary

This is not the case. Yesterday I watched .NET 4.5: Portable Libraries by David Kean and Mircea Trofin at Channel 9. It all made more sense to me.

 

The show:

  • The first 15 minutes explains portability and the first version of the Portable Class Libraries Project.
  • 15:00 whiteboard time.
  • Explaining the first way to solve portability problem:
  • wb1
  • wb2
  • Explaining the problems with System.NET
  • wb3
  • 22:00 the new solution: one portable library by design.
  • Portability is not an afterthought
  • 28:00
    • You program against a contract
    • It is up to the platform to implement the contract
    • Type forwarding:
      wb5
    • You program against the exposed api.
    • wb4
    • And the GAC will forward to dll that implements the actual code.
    • 33:00 Portability is a first class citizen
  • 35:00 It is about granularity a method is too small a dll is too big.
  • 36:00
    • Q: Are there two gacs in the Windows 8 world?
    • A: there is one gac. The metro mode is under “us”.
  • 37:00 breaking changes:
    • Type
    • wb6
    • wb7
  • 45:00 Close and Dispose. Close is disposed, no more closing just disposing.
  • They reference: A .NET developer's view of Windows 8 app development by Krzysztof Cwalina
  • 50:00 .NET has a great future with portability in mind.

So it makes sense to fix and recompile your legacy libraries. You can port them to all platforms that will have .NET available.

Total Pageviews