(Newbie question). My main application is running in F#. From the F# application, I am calling a print routine on a separate background thread. This print routine uses the below wpf xaml usercontrol in a separate C# project to format the page.
My problem is that the Account object is defined in F# and used in C# -- except that it does not work.
Error: The type 'Account' is not compatible with the type 'IAccount'
Is there anyway to have these two languages play nice together?
(Is FsXaml a possibility?)
Thanks for any help or suggestions.
TIA
F#
let workSheetHeader (a:Account) (encounterTime: Nullable<DateTime> ) =
let Insurance = "Self Pay"
let firstEncounter,lastEncounter = getFirstAndLastEncounter(a,encounterTime)
let account = {Account.birthDate = "11/30/1999"; lastName = "lastname"; firstName = "firstname"; chartNumber = 1776; doNotSee = false; mi ="i" }
let ws = new WorksheetHeader (account, firstEncounter, lastEncounter, Insurance)
ws :> FrameworkElement
WPF XAML
<UserControl x:Class="StargateIX.PrintingAndReports.WorksheetHeader"
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"
xmlns:local="clr-namespace:StargateIX.PrintingAndReports"
mc:Ignorable="d"
d:DesignHeight="70" d:DesignWidth="816">
<UserControl.Resources>
<!--Without the x:Key, this will style ALL the TextBlocks-->
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="12" />
</Style>
<Style x:Key="Title" TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="14" />
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
</UserControl.Resources>
<Grid>
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="24,0" >
<TextBlock Text="address 1" />
<TextBlock Text="address 2" />
<TextBlock Text="address 3" />
</StackPanel>
<StackPanel HorizontalAlignment="Right" VerticalAlignment="Top" Margin="24,0">
<TextBlock Text="Chart Number" Name="textblockChartNumber" />
<TextBlock Text="Bd: 4/15/1960" Name="textblockBirthDate" />
<StackPanel Orientation="Horizontal">
<!--Last Encounter Date-->
<TextBlock Text="First Visit: " />
<TextBlock Text="{Binding FirstEncounter}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<!--Last Encounter Date-->
<TextBlock Text="Last Visit: " />
<TextBlock Text="{Binding LastEncounter}" />
</StackPanel>
</StackPanel>
<TextBlock
Style="{StaticResource Title}" Name="textblockPatientName"
Text="Test Name" Width="332" Margin="242,0,242,0" />
<!--Today's Date-->
<TextBlock x:Name="textblockTodaysDate" HorizontalAlignment="Left" Margin="368,33,0,0" Text="11/04/2015" VerticalAlignment="Top"/>
<!--Insurance-->
<TextBlock HorizontalAlignment="Left" Height="16" Margin="24,48,0,0" Text="{Binding Insurance}" VerticalAlignment="Top" Width="209"/>
</Grid>
</UserControl>
Code Behind:
using System;
using System.Windows.Controls;
namespace StargateIX.PrintingAndReports
{
public interface IAccount
{
string lastName { get; }
string firstName { get; }
string mi { get; }
string birthDate { get; }
int chartNumber { get;}
bool doNotSee { get;}
}
/// <summary>
/// Interaction logic for WorksheetHeader.xaml
/// </summary>
public partial class WorksheetHeader : UserControl
{
public WorksheetHeader(IAccount account, DateTime? firstEncounter, DateTime? lastEncounter, string insurance)
{
DataContext = this;
FirstEncounter = firstEncounter;
LastEncounter = lastEncounter;
Insurance = insurance;
InitializeComponent();
// var model = new ServiceService(service);
textblockTodaysDate.Text = DateTime.Today.ToShortDateString();
// textblockBirthDate.Text = $"Bd: {account.birthDate:D}";
// textblockChartNumber.Text = $"C#: {account.chartNumber}";
// textblockPatientName.Text = PatientNameService.ProperName(account);
}
public DateTime? FirstEncounter { get; private set; }
public string Insurance { get; private set; }
public DateTime? LastEncounter { get; private set; }
}
}
#Addendum: As suggested below, I moved the definition and interface in F# to its own project, then referenced this project from the C# XAML. It now at least compiles. Here is the new definitions (in its own project):
module Contracts =
type IAccount =
abstract member lastName : string with get
abstract member firstName : string with get
abstract member mi : string with get
abstract member birthDate: string with get
abstract member chartNumber: int with get
abstract member doNotSee: bool with get
type Account =
{
lastName: string
firstName: string
mi: string
birthDate: string
chartNumber: int
doNotSee: bool
}
interface IAccount with
member this.birthDate with get() = this.birthDate
member this.chartNumber with get() = this.chartNumber
member this.doNotSee with get() = this.doNotSee
member this.firstName with get() = this.firstName
member this.lastName with get() = this.lastName
member this.mi with get() = this.mi
Is there any other way, or perhaps a better way of doing this?
TIA
If you are only exposing the interface, are not concerned about the concrete type, you can also use an object expression.
type IAccount =
abstract member lastName : string with get
abstract member firstName : string with get
let createAccount fstName lstName =
{ new IAccount with
member _.firstName = fstName
member _.lastName = lstName
}
A record implementing the interface is good as well. F# forces you to have acyclic dependencies, so plan ahead.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.