Category Archives: Silverlight

Silverlight Navigation Frame in F#

This is again a quick post based on my daily findings as I work more into Silverlight and other frameworks with F#. The Silverlight Navigation Frame allows us to provide deep linking within Silverlight applications. It uses a NavigationFrame control and hosts a “Page” instead of UserControl. This is very useful when developing large enterprise apps and also provides SEO friendly URIs (if you are building something online).

I faced a couple of problems when using F#, because the Navigation frames were based purely on XAML code and it interacted with the C# code using partial classes. As you all know F# doesn’t provide “partial” classes, I was looking to find an alternative to customize this design. Luckily with Silverlight 4, the navigation frame includes a “ContentLoader” property which is of type INavigationContentLoader. It has some extensible methods that allows customization to define the mapping, that was it and I implemented the below code to wrap it around Types instead of plain URIs. This would allow the navigation frame to invoke an object of the type and then we load the Page in the implementation of the type. This lets us use F# code purely with XAML to be used for UI declaration.

type TypeContentLoader() =
    
    let getTypeNameFromUri(uri : Uri) =
        let mutable contentUri = uri
        if not(uri.IsAbsoluteUri) then
            contentUri <- new Uri(new Uri("dummy:///", UriKind.Absolute), uri.OriginalString)
        Uri.UnescapeDataString(contentUri.AbsolutePath.Substring(1))

    interface INavigationContentLoader with
    
        member x.CanLoad(targetUri : Uri, currentUri : Uri) =
            let typeName = getTypeNameFromUri(targetUri)
            let t = Type.GetType(typeName, false, true)
            let mutable result = true
            if t = null then
                result <- false
            let defaultConstructor = t.GetConstructor(Array.empty<Type>)
            if defaultConstructor = null then
                result <- false
            result

        member x.CancelLoad(asyncResult : IAsyncResult) =
            ()

        member x.BeginLoad(targetUri : Uri, currentUri : Uri, userCallback : AsyncCallback, asyncState : obj) =
            let t = Type.GetType(getTypeNameFromUri(targetUri), false, true)
            let instance = Activator.CreateInstance(t)         
            let asyncResult = new AsyncResultNoResult(userCallback, asyncState)   
            asyncResult.Result <- instance
            asyncResult.SetAsCompleted(null, true)
            upcast asyncResult            
            
        member x.EndLoad(asyncResult : IAsyncResult) =
            let container = asyncResult : ?> AsyncResultNoResult            
            new LoadResult(container.Result)

 

We simply set the navigation frame’s ContentLoader property with the above instance,

        <sdk:Frame x:Name="ContentFrame"
                   Grid.Row="1">
            <sdk:Frame.ContentLoader>
                <common:TypeContentLoader />
            </sdk:Frame.ContentLoader>
        </sdk:Frame>

 

Then declare a HyperlinkButton to navigate to the particular type,

            <HyperlinkButton Content="Home"
                             NavigateUri="FSharpSilverlightApp1.Home"
                             TargetName="ContentFrame"
                             Margin="4" />

That’s it, It is now easy to separate your view concerns based on namespaces. Hope this helps in using F# more easily!

Download the sample from here.

-Fahad

Advertisements

Bing RESX .NET Helper

I’m working on one consulting project in Silverlight and it had lots of localization features to be done, I had to construct the English language so that was easy. After that it was the turn for converting this RESX to 4 other languages, By the thought of doing it line-by-line I was more sleepy and lazy!

I did remember that once Dr. Don Syme had shown some samples of using Bing translator in JAOO tutorials. Quickly took that sample source and looked over it for 5 mins to get this working in this use case. Then it hardly took 20 mins to put up a script file and get my work done, that was the sweet spot, I did the below things,

  • Connected to BING API service “async”hronously
  • Read from the resources txt file
  • Passed each line to BING for translating
    • Each request is a parallel execution
    • Used async continuations to process out the results

That’s it, so it just took 20 mins and saved me the whole day’s work! I’m pretty sure most .NET apps have requirement of having it localized in various languages, this is one way to get your work done. You can take a look at the source code in github, https://github.com/fahadsuhaib/FSharpTools. Check out the readme to know how to use it.

-Fahad

You can follow me on Twitter – @fahadsuhaib

F# Quotations for INotifyPropertyChanged

I was wanting to use F# quotations with INotifyPropertyChanged for quite sometime now, Since I’m working on pure usage of F# in WPF and Silverlight this is one part that would help using F# with Visual Studio. There are lots of ViewModelBase implementation in C# that utilizes the LINQ expressions when you want to declare CLR properties. The LINQ Expression<Func> allows you to write strongly typed code in C# for defining the property,

private object selectedItem = null
public object SelectedItem
{
	get{ return this.selectedItem; }
	set
	{
		if(this.selectedItem != value)
		{
			this.selectedItem = value;
			this.OnPropertyChanged(() => this.SelectedItem)
		}
	}
}

The above code uses a strongly-typed OnPropertyChanged method that in-turn parses out the property name and passes that to the INotifyPropertyChanged interface.

Now that I’m officially working on full-time F# work, I was happy to get this done. Below code shows the ViewModelBase implementation utilizing the F# quotations,

open System
open System.Collections.ObjectModel
open System.ComponentModel
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns

type ViewModelBase() =
    let propertyChanged = new Event<_, _>()
    let toPropName(query : Expr) = 
        match query with
        | PropertyGet(a, b, list) ->
            b.Name
        | _ -> ""

    interface INotifyPropertyChanged with
        [<CLIEvent>]
        member x.PropertyChanged = propertyChanged.Publish

    abstract member OnPropertyChanged: string -> unit
    default x.OnPropertyChanged(propertyName : string) =
        propertyChanged.Trigger(x, new PropertyChangedEventArgs(propertyName))

    member x.OnPropertyChanged(expr : Expr) =
        let propName = toPropName(expr)
        x.OnPropertyChanged(propName)

To use the above, You need to inherit the ViewModelBase to your custom type and then call the OnPropertyChanged method with the F# quotations. Below is an example showing how to declare the same “SelectedItem” property in F#,

    let mutable selectedItem : obj = null

    member x.SelectedItem
        with get() = selectedItem
        and set(v : obj) = 
            selectedItem <- v
            x.OnPropertyChanged(<@ x.SelectedItem @>)

The F# quotations are wrapped around <@@> block, this is the syntax in F#. Now you get full intelli-sense with Visual Studio too,

image

Also, added this in the F# snippets site here.

Hope this helps.

-Fahad