【问题标题】:Can I create a StackLayout with F# in Xamarin Forms?我可以在 Xamarin Forms 中使用 F# 创建 StackLayout 吗?
【发布时间】:2015-04-22 05:15:33
【问题描述】:

在他的Xamarin 3 F# Awesomeness 博客帖子中,Dave Thomas 显示了正在创建的 StackLayout:

StackLayout.Create(
            [ 
              Entry (Placeholder = "Username") 
              Entry (Placeholder = "Password", IsPassword = true) 
              Button (Text = "Login", TextColor = Color.White, BackgroundColor = Color.FromHex "77D065") 
            ],...

但是,我收到一个错误字段、构造函数或成员“创建”未定义

如果我在括号前取出.Create,错误消息将更改为对象构造函数'StackLayout'的成员接受0个参数,但这里给出1。

我的解释是 Create 是一个采用元组的静态方法,但我在程序集浏览器的任何地方都看不到它的定义。 我在他的示例中也对 TabbedPage 上使用的小写 create 感到有些困扰,因此看起来代码不一致,并且可能在没有编译的情况下输入,尽管他在下面显示了屏幕截图。

我会接受有关如何执行此操作的任何建议 - 如果没有缺少添加 Create 的神奇扩展,我很乐意采用其他方法。

父类声明in the docs是:

[Xamarin.Forms.ContentProperty("Children")]
public abstract class Layout<T> : Layout,   IViewContainer<T>
where T : Xamarin.Forms.View

我认为有一个习惯用法可以将 Children 属性设置为 C# 的初始化,但可能不适用于 F#?

例如,我从Forms Gallery sample 获得了编译代码,例如:

        StackLayout stackLayout = new StackLayout
        {
            Spacing = 0,
            VerticalOptions = LayoutOptions.FillAndExpand,
            Children = 
            {
                new Label
                {
                    Text = "StackLayout",
                    HorizontalOptions = LayoutOptions.Start
                },

我尝试将其转录为 F# 语法 - 以下是合法语法,但设置了 Children 属性时出现错误 对象构造函数“StackLayout”的成员没有参数或可设置的返回属性“Children”。所需的签名是 StackLayout(): unit。 (FS0495)

  type App() = 
   static member GetMainPage =
    let sl = new StackLayout (
                  Spacing = 20,
                  VerticalOptions = LayoutOptions.FillAndExpand,
                  Children = [
                    new Label (Text = "StackLayout");
                    new Label (Text = "SuckLayout")
                  ]       
   )
   new ContentPage( Content = sl )

所以,让我感到困惑 - 我不知道为什么可以从 C# 而不是 F# 访问 Children。唯一有意义的怀疑是 XAML 内容属性注释以某种方式对一个编译器而不是另一个编译器产生影响。

我是一位非常有经验的 C++ 和 Python 程序员,正在学习 F#(和 Swift),所以我很可能会在语法上绊倒。我得到了元组,我已经习惯了逗号的奇怪角色,谢天谢地,我的 Python 背景让我对空格感到放松。

其他人在博客帖子的 cmets 中提出了相同的问题,但没有发布答案。

我正在使用 Xamarin.iOS 8.10.0.258 Xamarin.Forms 1.4.0.6341

我的后备方案是放弃 F# 的 GUI 并使用 C# 和 F# 的主要逻辑,但我真的很喜欢更紧凑的语法。


请注意,我也在他们的 forums 上问过这个问题

【问题讨论】:

  • 我对 xamarin.forms 毫无头绪 - 但基于 docs(?) 在此类上没有(静态)方法 Create,我猜它已被删除。
  • 我同意,这是我的怀疑,或者他使用了一些扩展方法并且没有记录。问题已相应更新。

标签: f# xamarin xamarin.forms


【解决方案1】:

您展示的 C# 代码使用 C# 的集合初始化器功能,它将编译为对 Children.Add() 的调用,它没有设置 Children 属性。

F# 没有相同的集合初始化器功能,因此您必须手动调用 Children.Add(),这很可能是 StackLayout.Create 函数正在执行的操作。

StackLayout.Create 函数可以是在名为 StackLayout 的模块中定义的本地函数,这可以解释为什么您在文档中看不到它。

【讨论】:

    【解决方案2】:

    感谢上面的 Leaf Garland,这是固定功能 - 我只需要 C# 使用 Add 的提示。

    type App() =  
     static member GetMainPage =
      let sl = new StackLayout (
                Spacing = 20.0,
                VerticalOptions = LayoutOptions.FillAndExpand
        )
      let slc : View[] = [|
        new Entry (Placeholder = "Username") 
        new Entry (Placeholder = "Password", IsPassword = true) 
        new Button (Text = "Login", TextColor = Color.White, BackgroundColor = Color.FromHex "77D065") 
      |]
      slc |> Seq.iter (fun vc -> sl.Children.Add(vc))
      new ContentPage( Content = sl )
    

    请注意,我必须创建临时变量 slc 才能获得类型为超类 View 的数组

    如果你有所有相同的类型,你可以使用文字列表和稍微简单的代码,如下所示:

    type App() =  
     static member GetMainPage =
      let sl = new StackLayout (
                Spacing = 20.0,
                VerticalOptions = LayoutOptions.FillAndExpand
        )
      [
        new Label (Text = "StackLayout")
        new Label (Text = "SuckLayout")
      ] |> Seq.iter (fun vc -> sl.Children.Add(vc))
      new ContentPage( Content = sl )
    

    Here's a nice article 关于 C# 集合初始化器,如果你有兴趣的话。

    我今晚太忙了,但会尝试编写 StackLayout.Create 函数作为练习。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 2012-08-20
      • 2017-05-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多