从视图函数创建Xamarin.Forms.DataTemplate
CollectionView或ListView提供了一种查看T类型对象序列的方法。与StackLayout或Grid相比,它的优点是只在需要时加载视图 为每个对象指定视图的自然方式是提供函数v:T->view F 但是,CollectionView/ListView需要一个数据模板。API与绑定紧密相连,因此API不自然、不提供信息且类型不安全。有用的属性似乎是IDictionary类型的值从视图函数创建Xamarin.Forms.DataTemplate,xamarin.forms,f#,Xamarin.forms,F#,CollectionView或ListView提供了一种查看T类型对象序列的方法。与StackLayout或Grid相比,它的优点是只在需要时加载视图 为每个对象指定视图的自然方式是提供函数v:T->view F 但是,CollectionView/ListView需要一个数据模板。API与绑定紧密相连,因此API不自然、不提供信息且类型不安全。有用的属性似乎是IDictionary类型的值 有没有可能绕过这个API,创建一个接受v:T->视图并返回数据模板的函数?这将允许为DataTempla
有没有可能绕过这个API,创建一个接受v:T->视图并返回数据模板的函数?这将允许为DataTemplate以及ListView和CollectionView创建一个干净的API。解决方案是使用DataTemplateSelector 以下是此网站的链接:-
您可以做的是从API调用中获取DataTemplate Id,并根据该Id选择特定的DataTemplate。您将需要制作那么多数据模板并存储在页面的Xaml中。这将是最安全、最简单的解决方案。实现这一点的一种方法是创建自己的DataTemplate和ViewCell DataTemplate只需要从ViewCell派生的类型在ListView需要时进行实例化。 然后,它调用这个新创建/重用的ViewCell的OnBindingContextChanged方法,并传递元素的相应值 此时,您可以访问ViewCell.View属性,该属性将包含要显示的控件。 您可以在那时执行您的函数 在您的情况下,由于您有一个“T”列表,因此如下所示:
type FuncViewCell(createFunc: 'T -> View) =
inherit ViewCell()
override x.OnBindingContextChanged () =
let data = x.BindingContext :?> 'T
x.View <- createFunc data
type FuncDataTemplate(createFunc: 'T -> View) =
inherit DataTemplate(fun () -> FuncViewCell(createFunc))
(...)
let createViewForData data =
Button(Text = data.Text)
let listView = ListView()
listView.ItemTemplate <- FuncDataTemplate(createViewForData)
listView.ItemsSource <- dataSource
----
Or even directly:
type FuncListView(createFunc) =
inherit ListView(DataTemplate = FuncDataTemplate(createFunc))
let listView = FuncListView(createViewForData)
listView.ItemsSource <- dataSource
类似的方法也可以在Fabulous.xamarin表单中找到
不同之处在于元素具有自己的视图创建功能。因此,无需扩展DataTemplate来传递函数
此外,您还可以使用Xamarin.Forms的BindableLayout将任何网格或StackLayout转换为使用DataTemplate。。您似乎建议DataTemplates/DataTemplateSelector可以表示任意函数,尤其是图灵完全函数。我对此表示怀疑,因为DataTemplateSelector甚至不是递归的。但即使这是真的,它也需要对视图函数v进行反向工程,结果会导致非常复杂和不可概括的代码。NB Xaml与这个问题无关。一种方法是:1。创建一个类型BindContainert:T=member this.Contents=T,其中内容被更改为可绑定的友好内容。2.与其作为项传入一个T列表,不如传入一个BindContainer列表,将此列表转换为一个可观察集合,使其易于绑定。3.使用创建ContentView的函数定义DataTemplate,使用.SetBindingContentView.ContentProperty、Contents在其上设置绑定并返回它。如果以前在代码中使用过绑定的人能够充实/简化这个想法,那就太好了。