Implementing ValueConverters in F#

I recently learned how to implement ValueConverters in F#.

In case you haven’t realized, I have been experimenting with F# on my off time so that I can be a better developer and thus increase both my worth and influence within the software development industry.

ValueConverters serve as translators for data binding. Specifically, they convert values of one type to another type. Meaning that a property of one type within a viewmodel can be translated to a property of another type within a XAML file.

Suppose we had the following Domain:

module ManageModule.Entities
 
type Duration = { 
    Hours:int
    Minutes:int
    Seconds:int 
}
 
type String20 = String20 of string
 
type Name = { 
    First:String20
    Last:String20
    Suffix:String20 option 
}
 
type Module = { 
    Author:Name
    Duration:Duration 
}
 
and Section = 
    | Introduction of Module
    | Conclusion of Module
    | Content of Module list

 

Next, suppose we had the following viewmodel:

namespace ManageModules
 
    open System.Windows.Input
    open UILogic.State
    open UILogic.Interaction
    open ManageModule.Entities
    open System.Collections.ObjectModel
 
    type CreationViewModel() =
        inherit ViewModelBase()
 
        let mutable (_modules:Module ObservableCollection) = ObservableCollection()
 
        let name =       { First=String20("Scott"); Last=String20("Nimrod"); Suffix=None }
        let duration =   { Hours=1; Minutes=30; Seconds=0 }
        let moduleItem = { Author=name; Duration=duration }
 
        do _modules.Add(moduleItem)
 
        member this.Modules
            with get()     = _modules
            and set(value) = _modules <- value
 
        member this.Add moduleItem = 
            _modules.Add(moduleItem)

Then, suppose we had the following XAML:

<Window x:Class="Client.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Client"
        xmlns:manageModules="clr-namespace:ManageModules;assembly=ManageModules"
        xmlns:converters="clr-namespace:ManageModules.Converters;assembly=ManageModules"
        mc:Ignorable="d"
        Background="Black"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <manageModules:CreationViewModel />
    </Window.DataContext>

    <Window.Resources>
        <converters:SomeValueConverter x:Key="SomeValueConverter" />
    </Window.Resources>

    <Grid>
        <ListView ItemsSource="{Binding Modules}" Background="Black">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Author.First, Converter={StaticResource SomeValueConverter}}"
                               Foreground="LightBlue" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Window>

We could implement our ValueConverter like this:

namespace ManageModules.Converters

open System.Windows.Data
open ManageModule.Entities

type SomeValueConverter() =
    interface IValueConverter with
        member x.Convert(value, targetType, parameter, culture) = 
            let string20 = value :?> String20
            match string20 with String20 v -> v :> obj

        member x.ConvertBack(value, targetType, parameter, culture) = failwith "Not implemented yet"
Advertisements
1 comment

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s