How to use F# modules from C# XAML for DataTemplates and DataContext?

Viewed 110

I am starting to learn F#/Elmish from the top down. I have found alot of information on F#, but very little on moving from C# to F#.

my topmost XAML is:

<Window x:Class="Views.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:Views"
        xmlns:models="clr-namespace:Models;assembly=Models"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.DataContext>
        <models:Contact/>
    </Window.DataContext>

    <Grid>
        <TabControl ItemsSource="{Binding Details}">
            <TabControl.ItemContainerStyle>
                <Style TargetType="{x:Type TabItem}">
                    <Setter Property="Header" Value="{Binding Name}" />
                </Style>
            </TabControl.ItemContainerStyle>
            <TabControl.Resources>
                <DataTemplate DataType="{x:Type models:ContactDetails}">
                    <local:ContactDetailsView />
                </DataTemplate>
                <DataTemplate DataType="{x:Type models:Internet}">
                    <local:InternetView/>
                </DataTemplate>
                <DataTemplate DataType="{x:Type models:PhoneNumbers}">
                    <local:PhoneNumbersView/>
                </DataTemplate>
                <DataTemplate DataType="{x:Type models:Addresses}">
                    <local:AddressesView/>
                </DataTemplate>
            </TabControl.Resources>
        </TabControl>
    </Grid>
</Window>

THIS DOES NOT COMPILE.

There are multiple errors here. The "MainWindow" is a C# XAML view.

xmlns:models="clr-namespace:Models;assembly=Models" refers to an F# project (called Models) where ContactDetails is defined as:

namespace Models

module ContactDetails = 
    open System
    open Elmish
    open Elmish.WPF

    /// This is the data model for ContactDetails
    type Model =
        {
            Name: string
            Content: string
            Text: string
        }

    /// This is used to define the initial state of ContactDetails
    let init =
        { Name = "Contact Details"
          Content = "Contact Details Content"
          Text = "Here I Am" }

    /// This is a discriminated union of the available messages from the user interface
    type Msg =
        | None
        | TextInput of string
        | Submit

    /// This is the Reducer Elmish.WPF calls to generate a new model based on a message and an old model
    let update msg m =
        match msg with
        | TextInput s -> { m with Text = s }
        | Submit -> m  // handled by parent
       

    /// Elmish uses bindings() to provide the data context for your view based on a model
    let bindings () : Binding<Model, Msg> list = [
        // One-Way Bindings
        "Name" |> Binding.oneWay (fun m -> m.Content)
        "Content" |> Binding.oneWay (fun m -> m.Content)
    ]

The Internet, phonenumbers, and addresses are defined exactly like the contactdetails.

The Views are all defined in a project (called views -- C#) like:

<UserControl x:Class="Views.ContactDetailsView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <TextBlock Text="{Binding Content}" />
    </Grid>
</UserControl>

All the views are defined the same way.

So, my newbie questions are really simple:

  1. Although everything compiles without error, at run-time, the clr is unable to locate the "Models" project or file. How to fix this?
  2. Assuming I can get this to recognize the F# project "Models", how do I correctly set the datacontext to an F# module?
  3. What would be an observablecollection to F#? (as in "Details" below?)
  4. Can a DataTemplate be used to address an F# datatype from the C# xaml? If so how?

Any help with these things would be most appreciated as I do best with a top down approach when learning. :)

TIA

Edit#1. Solved the "unable to find file Models". I forgot to add the Models project to the references in the Views project.:(

0 Answers
Related