微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Xamarin 的 ViewModel 中绑定来自 Bindablelayout.ItemTemplate 的数据

如何解决在 Xamarin 的 ViewModel 中绑定来自 Bindablelayout.ItemTemplate 的数据

我在 Dynamically adding Entry Controls 遇到了一个问题,Wendy Zang - MSFT 帮助并解决了它。

从API获取条目列表的代码写在.xml.cs页中,在.xml页中,StackLayout的Bindablelayout.ItemTemplate用于设置 Entry 模板。

它运行良好,但提交表单的代码是用 viewmodel 编写的。

当我将 .xml.cs 页面代码粘贴到 viewmodel 中时,我无法获取条目,并且当代码xml.cs 中时,我必须为其设置 {{1 this.BindingContext = this; 中的 }} 代码未执行。

.xml

viewmodel

xml.cs

<StackLayout BindableLayout.ItemsSource="{Binding forms}">
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            <Entry Name="{Binding name}" Placeholder="{Binding label}" />
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</StackLayout>

XAML 和 viewmodel 中的按钮

RootObject list = JsonConvert.DeserializeObject<RootObject>(fields);

forms = new List<Form>();
forms = list.data.FirstOrDefault().Form.ToList();

this.BindingContext = this;
<Button
x:Name="SubmitButton"
Text="Submit"
Command="{Binding FormCommand}">

更新

从服务器获取动态字段的代码

public ICommand FormCommand=> new Command(async (x) => await FormButton(default,default));

解决方法

如果你想用 ViewModel 做到这一点,你可以参考下面的代码。

XML:

      <StackLayout>
        <Button
    x:Name="SubmitButton"
    Text="Submit"
    Command="{Binding FormCommand}"></Button>
        <StackLayout x:Name="DynamicEntry" BindableLayout.ItemsSource="{Binding forms}">
            <BindableLayout.ItemTemplate>
                <DataTemplate>
                    <Entry Placeholder="{Binding label}" MaxLength="{Binding max_length}" />

                </DataTemplate>
            </BindableLayout.ItemTemplate>
        </StackLayout>
    </StackLayout>

背后的代码:

public partial class MainPage : ContentPage
{

    public MainPage()
    {
        InitializeComponent();

        this.BindingContext = new ViewModel();
    }
}

视图模型:

public class ViewModel
{
    public List<Form> forms { get; set; }
    public ICommand FormCommand { get; set; }
    public ViewModel()
    {
        CreateCollection();
        FormCommand = new Command(async (x) => await FormButton(default,default));
    }

    private Task FormButton(object p1,object p2)
    {
        return Task.Delay(2000);
    }

    public void CreateCollection()
    {
        var json = @"{
'success': 'true','data': [
{
    'form': [
        {
            'label': 'Name','name': 'name','type': 'text','max_length': '15','required': 'true'
        },{
            'label': 'Email','name': 'email','type': 'email','max_length': '30','required': 'true'
        }
    ]
}
]
}";
        var list = JsonConvert.DeserializeObject<Rootobject>(json);

        forms = new List<Form>();
        forms = list.data.FirstOrDefault().form.ToList();
    }
}

输出:

enter image description here

,

要完全理解,请查看 @Wendy's 解决方案。问题是,当页面打开时没有出现表单,但是当我处于调试模式并刷新 .xml 页面时,它出现了。

@Shaw 建议使用 ObservableCollection<> 而不是 List<>,但是在 list.data.FirstOrDefault().form.ToList(); 上它说 cannot convert 'System.Collection.Generic.List' 'System.Collections.ObjectModel.ObservableCollection'.

我修复了它......这是完整的解决方案。

private ObservableCollection<Form> _forms = new ObservableCollection<Form>();
public ObservableCollection<Form> Forms
{
    get
    {
        return _forms;
    }
    set
    {
        this.RaiseAndSetIfChanged(ref _forms,value);
    }
}
var list = JsonConvert.DeserializeObject<Rootobject>(json);

foreach (var i in list.data.Where(c => c.id == ""))
{
    _forms.Add(i.form.ToList());
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。