问题描述
我在 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();
}
}
输出:
,要完全理解,请查看 @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());
}