在F#中的自定义控件上创建Xamarin.Forms BindableProperty

Lam*_*rth 5 xaml f# xamarin xamarin.forms

我有F#+ Xamarin.Forms,没有实际使用C#。它工作正常,但是现在我正在尝试在要创建的控件上创建BindableProperty。它有点有效,但是当我尝试在XAML中使用{DynamicResource blah}或在带有Style的样式中进行绑定时,一切都会崩溃。

两者都起作用:

<dashboard:ProgressRing DotOnColor="#00d4c3" DotOffColor="#120a22" />
<dashboard:ProgressRing DotOnColor="{StaticResource dotOnColor}" DotOffColor="{StaticResource dotOffColor}" />
Run Code Online (Sandbox Code Playgroud)

无法运作:

<dashboard:ProgressRing DotOnColor="{DynamicResource dotOnColor}" DotOffColor="{DynamicResource dotOffColor}" />
Run Code Online (Sandbox Code Playgroud)

错误:

Xamarin.Forms.Xaml.XamlParseException:位置18:29。无法分配属性“ DotOnColor”:属性不存在或不可分配,或者值和属性之间的类型不匹配

XAML:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="Dashboard.ProgressRing"
    x:Name="view">
  <AbsoluteLayout x:Name="absLayout">
    <!-- Dots are controlled in the code behind -->
  </AbsoluteLayout>
</ContentView>
Run Code Online (Sandbox Code Playgroud)

后面的代码:

namespace Dashboard

open System
open Xamarin.Forms
open Xamarin.Forms.Xaml

type ProgressRing() =
    inherit ContentView()

    do base.LoadFromXaml(typeof<ProgressRing>) |> ignore
    let absLayout = base.FindByName<AbsoluteLayout>("absLayout")

    static let dotOffColorProperty = BindableProperty.Create("DotOffColor", typeof<Color>, typeof<ProgressRing>, Color.Default)
    static let dotOnColorProperty = BindableProperty.Create("DotOnColor", typeof<Color>, typeof<ProgressRing>, Color.Accent)

    static member DotOffColorProperty = dotOffColorProperty
    static member DotOnColorProperty = dotOnColorProperty

    member this.DotOffColor
        with get () = this.GetValue dotOffColorProperty :?> Color
        and set (value:Color) =
            this.SetValue(dotOffColorProperty, value)
    member this.DotOnColor
        with get () = this.GetValue dotOnColorProperty :?> Color
        and set (value:Color) =
            this.SetValue(dotOnColorProperty, value)
Run Code Online (Sandbox Code Playgroud)

我认为,这是导致静态成员失败的原因-这是一个公共静态属性,Xamarin.Forms需要一个公共静态字段

F#正式不执行公共静态字段,这在诸如此类的情况下会引起问题-参见此处的一些讨论:http : //www.ianvoyce.com/index.php/2010/10/01/public-static-fields-gone-从-f-2-0 /

Lam*_*rth 2

Xamarin.Forms 肯定正在寻找一个字段 - 我在https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs中找到了以下内容:

    static BindableProperty GetBindableProperty(Type elementType, string localName, IXmlLineInfo lineInfo,
        bool throwOnError = false)
    {
        var bindableFieldInfo =
            elementType.GetFields().FirstOrDefault(fi => fi.Name == localName + "Property" && fi.IsStatic && fi.IsPublic);

        Exception exception = null;
        if (exception == null && bindableFieldInfo == null) {
            exception =
                new XamlParseException(
                    string.Format("BindableProperty {0} not found on {1}", localName + "Property", elementType.Name), lineInfo);
        }

        if (exception == null)
            return bindableFieldInfo.GetValue(null) as BindableProperty;
        if (throwOnError)
            throw exception;
        return null;
    }
Run Code Online (Sandbox Code Playgroud)

我想我也会尝试修复它以处理公共静态属性。完成之后,关于如何提交有什么提示吗?