首页 > 解决方案 > 如何将 C# XAML 中的 F# 模块用于 DataTemplates 和 DataContext?

问题描述

我开始自上而下地学习 F#/Elmish。我发现了很多关于 F# 的信息,但很少有关于从 C# 迁移到 F# 的信息。

我最上面的 XAML 是:

<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>

这不编译。

这里有多个错误。“MainWindow”是一个 C# XAML 视图。

xmlns:models="clr-namespace:Models;assembly=Models" 指的是一个 F# 项目(称为 Models),其中 ContactDetails 定义为:

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)
    ]

Internet、电话号码和地址的定义与联系人详细信息完全相同。

视图都在一个项目(称为视图——C#)中定义,例如:

<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>

所有视图都以相同的方式定义。

所以,我的新手问题很简单:

  1. 尽管一切编译都没有错误,但在运行时,clr 无法找到“模型”项目或文件。如何解决这个问题?
  2. 假设我可以让它识别 F# 项目“模型”,我如何正确地将 datacontext 设置为 F# 模块?
  3. F# 的 observablecollection 是什么?(如下面的“详情”?)
  4. 可以使用 DataTemplate 来处理 C# xaml 中的 F# 数据类型吗?如果有怎么办?

对这些事情的任何帮助将不胜感激,因为我在学习时最好采用自上而下的方法。:)

TIA

编辑#1。解决了“找不到文件模型”的问题。我忘记将 Models 项目添加到 Views 项目中的引用中。:(

标签: f#elmish-wpf

解决方案


推荐阅读