FS2024当TypeProvider使用PCL项目时出现静态链接错误

时间:2014-08-07 05:48:58

标签: f# type-providers xamarin.forms

它试图为Xamarin.Forms制作一个TypeProvider,但一直受到FS2024错误的困扰。

  • 从Xamarin.Forms的XAML中解析自己的库
  • 将x:名称分配给Propertis

`F#

type MainPage = Moonmile.XamarinFormsTypeProvider.XAML<"MainPage.xaml">
// made btn1 and text1 propertis

type MainPageEx(target:MainPage) =
    let mutable count = 0
    do
        // When set event to btn.Clicked, happen FS2024 error.
        // If this event is comment out, it success build.
        target.btn1.Clicked.Add( fun e ->
            count <- count + 1
            target.btn1.Text <- "Clicked " + count.ToString())
    // Property is success
    member this.CurrentPage
        with get() = target.CurrentPage

当您提到某个房产时,建造&amp;你可以正常操作。 但内部类的Xamarin.Forms喜欢Button.Clicked,如果你试图访问,那就是构建错误。

错误的示例代码 https://github.com/moonmile/SimpleEventTypeProvider

为XamarinFormsTypeProvider创建代码 github.com/moonmile/XamarinFormsTypeProvider

也许,我怀疑是不一致的,并且发生在Native TypeProvider和Xamrin.Forms.Core PCL的一代中。

F# Compiler for F# 3.1 (Open Source Edition)
Freely distributed under the Apache 2.0 Open Source License my error!!!
isMscorlib: true
name: "System.Runtime"
PrimaryAssembly.DotNetCore.Name: "System.Runtime"
PrimaryAssembly.Mscorlib.Name: "mscorlib"

parameter error FS2024: Static linking may not use assembly that targets different profile.

操作他们正常工作的属性,或者操作MVVM。 我试图实现一种分配给Button.Clicked事件的方法 如果可能的话,如同代码隐藏的建筑物所示。

会有解决方法还是什么?

对于WPF中的XAML,如何才能正常运行。 github.com/fsprojects/FsXaml

2 个答案:

答案 0 :(得分:2)

这个答案不能保证是正确的,但它至少应该帮助你找到正确的方向。

要做的第一件事是确保已安装最新的Visual F#Tools Build,因为这会添加与PCL配置文件兼容的FSharp.Core(您可以在此处找到它:(https://visualfsharp.codeplex.com/安装完成后,你需要引用Profile78或Profile259 FSharp.Core.dll(在我的机器上,可以在以下位置找到:“ C:\ Program Files(x86)\ Reference Assemblies \ Microsoft \ FSharp.NETPortable \ 2.3.5.0 “和” C:\ Program Files(x86)\ Reference Assemblies \ Microsoft \ FSharp.NETPortable \ 2.3.5.1 “。

安装完成后,接下来要确保您的PCL项目在其项目文件中具有以下内容(这告诉MSBuild / xBuild项目是PCL库,它们是F#项目):< / p>

<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{F2A71F9B-5D33-465A-A702-920D77279786}</ProjectTypeGuids>

完成后,您需要选择Profile78或Profile259(我建议使用78,因为当前的Xamarin.Forms nuget包不支持259)。

一旦完成,那么你应该能够构建和运行它应该摆脱错误。

答案 1 :(得分:0)

谢谢你的提问。

Meybe, 当它构建TypeProvider时,F#编译器使用mscorlib中的类。 当它解析btn1.Clicked事件的类型时,F#comiler在System.Runtime中使用类型。 我认为,并且它无法在构建时解决

尝试,如果您使用反射附加Clicked事件,它已在Android版本上成功移动。 我似乎,如果我在mscorlib和System.Rutime中只使用分片类,我可以建立没有FS2024错误。

type MainPage = Moonmile.XamarinFormsTypeProvider.XAML<"MainPage.xaml">

type MainPageEx() as this =
    inherit BindObject<MainPage>(new MainPage())

    // Add handlder by reflection
    let AddHandler(target:obj, eventName:string, eventMethod: obj*obj -> unit ) =
        let hdr = Action<obj,obj>( fun s e  -> eventMethod(s,e))

        let ei = target.GetType().GetRuntimeEvent(eventName)
        let dt = ei.AddMethod.GetParameters().[0].ParameterType
        let handler = new Action<obj,obj>(fun s e -> hdr.Invoke( s, new EventArgs() ))
        let handlerInvoke = handler.GetType().GetRuntimeMethod("Invoke", [|typeof<obj>; typeof<Type[]>|])
        let dele = handlerInvoke.CreateDelegate( dt, handler )
        let add = new Func<Delegate, EventRegistrationToken> ( fun t -> 
            let para = ei.AddMethod.GetParameters()
            let ret  = ei.AddMethod.Invoke( target, [|t|])
            if ret <> null then
                ret :?> EventRegistrationToken
            else
                new EventRegistrationToken()
            )
        let remove = new Action<EventRegistrationToken>( fun t -> ei.RemoveMethod.Invoke(target, [|t|]) |> ignore )
        // WindowsRuntimeMarshal.AddEventHandler<Delegate>(add, remove, dele)
        add.Invoke( dele ) |> ignore
        ()

        let mutable count = 0
        do
        (*  // build error
            target.btn1.Clicked.Add( fun e ->
                count <- count + 1
                target.btn1.Text <- "Clicked " + count.ToString())
        *)
            // add handler by reflection
            AddHandler( base.Target.btn1, "Clicked", this.ButtonClick ) 
            ()

        member this.CurrentPage
            with get() = this.Target.CurrentPage

        member this.ButtonClick(s,e) =
            count <- count + 1
            base.Target.text1.Text <- "clicked " + count.ToString()