Sunday, July 17, 2011

WPF Behaviors in the F# WPF Project Templates

In my last post, I mentioned that I was working on a few enhancements to the my F# WPF Project Templates that are out on Visual Studio Gallery. I'm happy to say that the new versions of the F# and C# Windows App (WPF, MVVM) and F# Windows App (WPF, MVVM) templates are now available.

What Was Changed?

For the F# Windows App (WPF, MVVM) template, a few WPF behaviors have been added. I'll talk about these changes in a bit (for those that can't wait, see http://fssnip.net/62 and http://fssnip.net/6h).

The F# and C# Windows App (WPF, MVVM) template includes all of the same changes as the F# only template. Additionally, I've taken the multiple F# projects that were previously provided in this template and coalesced them into one F# project. I believe that this change better reflects the real-world use of this template.

You Mentioned WPF Behaviors?

The biggest change to the templates is the addition of examples of a few different types of WPF behaviors. These templates include examples of event to command as well as a type converter. The event to command implementation is Blendable (meaning that it plays well with Expression Blend) and is loosely based on the MVVM Light Toolkit EventToCommand implementation.

Here's the code:

namespace FSharpWpfMvvmTemplate.Behavior

open System
open System.Windows
open System.Windows.Input
open System.Windows.Interactivity

type EventToCommand() =
    inherit TriggerAction<DependencyObject>()
    [<DefaultValue(false)>] 
    static val mutable private CommandProperty:DependencyProperty
    [<DefaultValue(false)>] 
    static val mutable private CommandParameterProperty:DependencyProperty
    
    /// Set the command dependency property
    static do 
        EventToCommand.CommandProperty <-
            DependencyProperty.Register("Command", 
                typeof<ICommand>, typeof<EventToCommand>)
    
    /// Set the command parameter dependency property
    static do 
        EventToCommand.CommandParameterProperty <-
            DependencyProperty.Register("CommandParameter", 
                typeof<obj>, typeof<EventToCommand>)
    
    /// Get/Set the Command 
    member this.Command 
        with get() = this.GetValue EventToCommand.CommandProperty :?> ICommand
        and set value = this.SetValue(EventToCommand.CommandProperty, value)
    
    /// Get/Set the CommandParameter 
    member this.CommandParameter 
        with get() = this.GetValue EventToCommand.CommandParameterProperty 
        and set value = this.SetValue(EventToCommand.CommandParameterProperty, value)
    
    /// Implement the Invoke method from TriggerAction to execute the command
    override this.Invoke parameter = 
        let command = this.Command
        let commandParameter = match this.CommandParameter with
                               | null -> parameter
                               | commandParam -> commandParam  
        if command <> null && command.CanExecute(commandParameter) then
            command.Execute(commandParameter)

Here's the XAML that uses this code:

        <Button Grid.Row="2" Command="{Binding ApproveExpenseReportCommand}" 
                Style="{StaticResource buttonStyle}" Content="Approve"
                Grid.Column="1" Margin="0,10,53,0">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter">
                    <Behavior:EventToCommand 
                            Command="{Binding MouseEnterButtonCommand}" 
                            CommandParameter="Approve" />
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseLeave">
                    <Behavior:EventToCommand 
                            Command="{Binding MouseLeaveButtonCommand}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>

The value converter example uses a ConverterBase class that simplifies the creation of any concrete implementations. This base class uses a combination of functional and object-oriented programming to provide a default implementation of Convert and ConvertBack. The child class can then provide a function to override the implementation of either or both of these methods. For the sake of brevity, I will not post the ConvertBase code here, but you can go to http://fssnip.net/62 to see it.

The concrete implementation that is provided as an example in these project templates is shown below:

namespace FSharpWpfMvvmTemplate.Behavior

open System
open System.Windows
open System.Windows.Data
open System.Windows.Media
open ConverterBase

/// Returns Visibility.Visible if the string is not null or empty
type StringExistsToVisibilityConverter() =
    inherit ConverterBase()
    let convertFunc = fun (v:obj) _ _ _ ->         
        match String.IsNullOrEmpty(string v) with
        | false -> Visibility.Visible
        | _ -> Visibility.Collapsed
        :> obj
    override this.Convert = convertFunc 

This can be used in XAML like this:

<TextBlock Grid.Row="3" HorizontalAlignment="Center" Margin="0,10,0,0" 
                FontSize="12" FontWeight="Bold" 
                Grid.ColumnSpan="2" Text="{Binding LastApprovalDisplayMessage}" 
                Visibility="{Binding Path=LastApprovalDisplayMessage, 
                            Converter={StaticResource StringExistsToVisibility}}" />

While I don't have an example in these templates of an Attached Property written in F#, it is worth noting that you can find just such an example at http://fssnip.net/69.

Tuesday, July 5, 2011

A Few Items of Note

In this post, I'm going to highlight a few things that I have been working on that aren't big enough to warrant their own blog entry, but that are worth pointing out. Note: If you follow me on Twitter (i.e. @dmohl) you may have already heard about these things.

1. In Feb. of this year, I blogged about the F# PowerPack being added to NuGet gallery. Since that time, there have been several requests to add the .NET 4 binaries to that NuGet package. I'm happy to say that a new version of the FSPowerPack.Community package has been uploaded that includes these binaries.

2. In Jan. of this year, an F# ASP.NET MVC 3 template was announced. There have been a few reports of an exception on some operating systems during the extension installation that points to a specific path that is too long. For those of you who are experiencing this error, there is a VSIX with a reduced path length available for download at https://sites.google.com/site/danodocs/Home/FSMVC3_min.vsix.

3. Have you visited the F# Snippets site yet? If not, I strongly recommend checking it out. While you are there, have a look at the WPF/Silverlight Value Converter base class and sample concrete implementation as well as an example of a WPF/Silverlight Attached Property. I'd love to hear what you think. Along these lines, I've been working on a few additions to the F# WPF templates that have been announced on this blog. If you have any enhancement requests, send them my way.


Thursday, June 30, 2011

F# XAML Item Templates Now on Visual Studio Gallery

A new VS2010 extension is now available on Visual Studio Gallery that provides several XAML related item templates for F# projects. The provided item templates include Window for WPF as well as Page, UserControl, and ResourceDictionary for Silverlight and WPF.

To get started, do the following:

1. Download and install the extension from http://visualstudiogallery.msdn.microsoft.com/06c6ece1-2084-4083-a0f7-934fce9d22fb or through the Extention Manager in Visual Studio 2010 as shown below (Extension Manager can be found under Tools -> Extension Manager..):


2. Once installed, you will see the following option available in the Add New Item wizard for F# Silverlight projects:


3. For F# WPF projects, the Add New Item wizard will look like the following:


These item templates complement the existing F# WPF and Silverlight project templates quite well. Here is a list of a few of these project templates that are currently available on Visual Studio Gallery:

Silverlight:

F# Web Application (Silverlight)

WPF:

F# App Template with Theme
F# Windows App (WPF, MVVM)
F# WPF Application

As usual you can find the source on my github (https://github.com/dmohl/FsXAMLItemTemplate).

Saturday, June 25, 2011

Version 1.3.0.1 of the F# and C# Win Phone App (Silverlight) Project Template Released

Version 1.3.0.1 of the basic WP7 project template has been released. The core feature of this release is a new item template that allows you to add a F# Source File in WP7 projects. Prior to this release, attempting to add a new item through the standard process resulted only in options targeting C#.

To take advantage of this new feature, do the following:

1. Install the 1.3.0.1 version of the project template (see this blog post for more information).
2. Right click on the F# project and select Add -> New Item...
3. The resulting window will now include a F# Source File item as shown below:


Thursday, June 2, 2011

FsUnit.MvcSample Now On NuGet Gallery

A new NuGet package is now available on the NuGet Gallery that makes it very easy to get started using FsUnit to test your ASP.NET MVC apps. The packageId is FsUnit.MvcSample and it can be found at http://nuget.org/List/Packages/FsUnit.MvcSample. For more information on FsUnit and the previously provided FsUnit NuGet package, check out http://bloggemdano.blogspot.com/2011/02/fsunit-now-on-nuget-gallery.html.

As usual, you can find everything used to create this package on my github (https://github.com/dmohl/FsUnit.MvcSample.NuGet).

Tuesday, May 24, 2011

Getting Started with FSRepository 2.0

FSRepository 2.0 is now available in the NuGet gallery. This version references EF 4.1, fixes an issue, and attempts to provide a more intuitive example.

Getting Started:

It's easy to get started with FSRepository 2.0.

1. Create a new F# Application (this example uses a project named TestFSRepository).
2. Follow the instructions defined in http://bloggemdano.blogspot.com/2011/01/fsrepository-new-nuget-package.html to install the FSRepository package.
3. Move the FSRepository.fs file above the Program.fs file (see http://lorgonblog.wordpress.com/2008/08/03/sneak-peeks-into-the-f-project-system-part-three/ for information on how to do this).
4. Add the following code to Program.fs and you're done.

open TestFSRepository.Repositories

type Program() = 
    static member Run() =
        use sampleRepository = new SampleRepository()
        let sample = new ASample()
        sample.Id <- 1
        sample.CreatedBy <- "Dan"
        do sampleRepository.Add sample
        do sampleRepository.Save()
        sampleRepository.GetAll()
        |> Seq.iter (fun (sample:ASample) -> 
                   (printfn "Sample Id = %A" sample.Id |> ignore))

Program.Run()

Tuesday, April 19, 2011

Today's Presentation for the Community for F#

Thanks to all who joined the Community for F# Live Meeting today. The people that make up the F# community are truly the best around! A big thanks also goes out to Ryan for putting all of this together month after month!

As mentioned during the presentation, here is the slide deck (plus the slide that I somehow deleted before the presentation), links to the samples that were shown, as well as a link to the Live Meeting video:

Video:



Slide Deck:
Examples:

VSIX Multi-Project Template: https://github.com/dmohl/FSharpWP7BasicTemplate
IWizard Implementation: https://github.com/dmohl/FSharpMVC3Starter
NuGet Package: https://github.com/dmohl/FSPowerPack.Community