【问题标题】:Creating a Xamarin.Forms BindableProperty on a custom control in F#在 F# 中的自定义控件上创建 Xamarin.Forms BindableProperty
【发布时间】:2017-06-06 09:28:11
【问题描述】:

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

两者都工作:

<dashboard:ProgressRing DotOnColor="#00d4c3" DotOffColor="#120a22" />
<dashboard:ProgressRing DotOnColor="{StaticResource dotOnColor}" DotOffColor="{StaticResource dotOffColor}" />

不工作:

<dashboard:ProgressRing DotOnColor="{DynamicResource dotOnColor}" DotOffColor="{DynamicResource dotOffColor}" />

错误:

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>

后面的代码:

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)

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

F# 官方不做公共静态字段,这会在这种情况下导致问题 - 请参阅此处的一些讨论: http://www.ianvoyce.com/index.php/2010/10/01/public-static-fields-gone-from-f-2-0/

【问题讨论】:

    标签: xaml xamarin f# xamarin.forms


    【解决方案1】:

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

    我想我也会尝试修复它以处理公共静态属性。在我这样做之后,关于如何提交的任何提示?

    【讨论】:

      猜你喜欢
      • 2018-03-03
      • 1970-01-01
      • 1970-01-01
      • 2018-10-21
      • 1970-01-01
      • 1970-01-01
      • 2020-01-30
      • 2021-04-20
      • 2019-08-16
      相关资源
      最近更新 更多