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"
One Reply to “Implementing ValueConverters in F#”