8 people like it.

A fun-ny WPF DataTemplate DSL

Parts of a little DSL to create WPF DataTemplate's in F#. Don't even want to think about the length of a corresponding C#. The F# code corresponds 1-to-1 to the visual tree constructed for the template.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
    let inline (|&) x a = x |> a |> ignore; x

    let inline fac<'T>() = FrameworkElementFactory(typeof<'T>)    
    let inline (<>=) o p v = ( ^a : (member SetValue   : DependencyProperty -> obj              -> unit) (o, p, v) )
    let inline (<>~) o p b = ( ^a : (member SetBinding : DependencyProperty -> Data.BindingBase -> unit) (o, p, Data.Binding b) )
    let inline (<>+) o v   = ( ^a : (member AppendChild : 'b -> unit) (o, v) )
    let inline (<>~<) o p (b,c) =
        ( ^a : (member SetBinding : DependencyProperty -> Data.BindingBase -> unit) (o, p, Data.Binding b |& fun x -> x.Converter <- c) )
    let makeValueConverter (f,g) =
        {
            new Data.IValueConverter with
                member this.Convert    (v, tt, p, c) = f v
                member this.ConvertBack(v, tt, p, c) = g v
        }
    let inline (>=<) (f : 'a -> 'b) (g : 'b -> 'a) = makeValueConverter (unbox >> f >> box,unbox >> g >> box)
    let inline (<>++) o vs = ((vs |> Seq.toArray) |>|! (<>+) o) |> ignore
    let inline (<>|+) o e h = ( ^a : (member AddHandler : RoutedEvent -> 'd -> unit) (o, e, h) )


//////////////////////////// USAGE


    let itemTemplate =

        let c2 = CORSIS.PDF.Windows.Documents.Overlays.reasonColor >> brush >=< fun _ -> ""

        DataTemplate() |& fun dt ->
            dt.DataType   <- typeof<Bookmark Choice>
            dt.VisualTree <- fac<StackPanel>() |& fun sp ->
                sp <>= StackPanel.OrientationProperty <| Orientation.Horizontal
                sp <>++
                    [
                        fac<TextBlock>() |& fun tb ->
                            tb <>~< TextBlock.TextProperty <| ("Value.PageIndex", (+) 1 >=< (-) 1)
                            tb <>=  TextBlock.FontFamilyProperty <| FontFamily "Consolas"
                            tb <>=  TextBlock.ForegroundProperty <| Brushes.LightGray
                        fac<TextBlock>() |& fun tb ->
                            tb <>=  TextBlock.TextProperty <| " "
                            tb <>~< TextBlock.BackgroundProperty <| ("Value.Reason", c2)
                            tb <>=  TextBlock.MarginProperty <| Thickness(4., 1., 4., 1.)
                        fac<TextBlock>() |& fun tb -> tb <>~  TextBlock.TextProperty <| "Value.Text"
                    ]
val x : 'a
val a : ('a -> 'b)
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
val fac<'T> : unit -> obj

Full name: Script.fac
val typeof<'T> : System.Type

Full name: Microsoft.FSharp.Core.Operators.typeof
val o : 'a (requires member SetValue)
val p : 'a
val v : 'b
type obj = System.Object

Full name: Microsoft.FSharp.Core.obj
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
val o : 'a (requires member SetBinding)
val b : 'c
namespace Microsoft.FSharp.Data
val o : 'a (requires member AppendChild)
val c : 'd
val x : 'b
val makeValueConverter : f:'a * g:'b -> 'c

Full name: Script.makeValueConverter
val f : 'a
val g : 'b
val f : ('a -> 'b)
val g : ('b -> 'a)
val unbox : value:obj -> 'T

Full name: Microsoft.FSharp.Core.Operators.unbox
val box : value:'T -> obj

Full name: Microsoft.FSharp.Core.Operators.box
val o : 'a
val vs : 'a (requires 'a :> seq<'b>)
module Seq

from Microsoft.FSharp.Collections
val toArray : source:seq<'T> -> 'T []

Full name: Microsoft.FSharp.Collections.Seq.toArray
val o : 'a (requires member AddHandler)
val e : 'a
val h : 'd
val itemTemplate : obj

Full name: Script.itemTemplate
val c2 : obj
val dt : obj
Multiple items
type Choice<'T1,'T2> =
  | Choice1Of2 of 'T1
  | Choice2Of2 of 'T2

Full name: Microsoft.FSharp.Core.Choice<_,_>

--------------------
type Choice<'T1,'T2,'T3> =
  | Choice1Of3 of 'T1
  | Choice2Of3 of 'T2
  | Choice3Of3 of 'T3

Full name: Microsoft.FSharp.Core.Choice<_,_,_>

--------------------
type Choice<'T1,'T2,'T3,'T4> =
  | Choice1Of4 of 'T1
  | Choice2Of4 of 'T2
  | Choice3Of4 of 'T3
  | Choice4Of4 of 'T4

Full name: Microsoft.FSharp.Core.Choice<_,_,_,_>

--------------------
type Choice<'T1,'T2,'T3,'T4,'T5> =
  | Choice1Of5 of 'T1
  | Choice2Of5 of 'T2
  | Choice3Of5 of 'T3
  | Choice4Of5 of 'T4
  | Choice5Of5 of 'T5

Full name: Microsoft.FSharp.Core.Choice<_,_,_,_,_>

--------------------
type Choice<'T1,'T2,'T3,'T4,'T5,'T6> =
  | Choice1Of6 of 'T1
  | Choice2Of6 of 'T2
  | Choice3Of6 of 'T3
  | Choice4Of6 of 'T4
  | Choice5Of6 of 'T5
  | Choice6Of6 of 'T6

Full name: Microsoft.FSharp.Core.Choice<_,_,_,_,_,_>

--------------------
type Choice<'T1,'T2,'T3,'T4,'T5,'T6,'T7> =
  | Choice1Of7 of 'T1
  | Choice2Of7 of 'T2
  | Choice3Of7 of 'T3
  | Choice4Of7 of 'T4
  | Choice5Of7 of 'T5
  | Choice6Of7 of 'T6
  | Choice7Of7 of 'T7

Full name: Microsoft.FSharp.Core.Choice<_,_,_,_,_,_,_>
Next Version Raw view Test code New version

More information

Link:http://fssnip.net/5e
Posted:13 years ago
Author:Cetin Sert
Tags: wpf , datatemplate , dsl