You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin中ViewModel如何获取BindableLayout.ItemTemplate绑定的Entry数据

问题根源说明

  1. 原代码中Entry没有绑定Text属性,输入内容无法同步到绑定的模型层,自然拿不到输入数据
  2. 后台代码设置this.BindingContext = this会覆盖指向ViewModel的绑定上下文,导致ViewModel的命令、绑定全部失效

步骤1:修改Form模型类

新增存储输入内容的属性,实现属性变更通知:

public class Form : INotifyPropertyChanged
{
    private string _name;
    public string name
    {
        get => _name;
        set { _name = value; OnPropertyChanged(); }
    }

    private string _label;
    public string label
    {
        get => _label;
        set { _label = value; OnPropertyChanged(); }
    }

    // 新增属性,存储Entry输入内容
    private string _value;
    public string Value
    {
        get => _value;
        set { _value = value; OnPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

步骤2:调整ViewModel代码

把接口拉取、数据集合、提交逻辑全部迁移到ViewModel中:

public class YourViewModel : INotifyPropertyChanged
{
    private ObservableCollection<Form> _forms;
    public ObservableCollection<Form> forms
    {
        get => _forms;
        set { _forms = value; OnPropertyChanged(); }
    }

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

    public YourViewModel()
    {
        // 初始化时拉取动态字段,也可以在页面生命周期中主动调用
        _ = CreateCollection();
    }

    public async Task CreateCollection()
    {
        Uri uri = new Uri("http://example.com/entry");
        HttpClient httpClient = new HttpClient(new NativeMessageHandler());
        HttpResponseMessage response = await httpClient.GetAsync(uri);
        string entries = await response.Content.ReadAsStringAsync();
        RootObject list = JsonConvert.DeserializeObject<RootObject>(entries);
        var formList = list.data.FirstOrDefault().form.ToList();
        forms = new ObservableCollection<Form>(formList);
    }

    private async Task FormButton()
    {
        // 直接遍历集合即可拿到所有动态Entry的输入值
        foreach (var item in forms)
        {
            var fieldName = item.name;
            var userInput = item.Value;
            // 处理提交逻辑即可
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

步骤3:清理页面后台代码(xml.cs)

删掉原有业务逻辑,仅绑定上下文到ViewModel实例:

public YourPage()
{
    InitializeComponent();
    // 不要绑定到this,直接绑定ViewModel实例
    this.BindingContext = new YourViewModel();
}

步骤4:修改XAML绑定规则

新增Entry的Text双向绑定:

<StackLayout BindableLayout.ItemsSource="{Binding forms}">
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            <!-- Entry的Name属性运行时绑定不生效,直接用模型的name字段标识即可 -->
            <Entry Placeholder="{Binding label}" 
                   Text="{Binding Value, Mode=TwoWay}" />
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</StackLayout>

<!-- 原有按钮绑定不用修改,直接生效 -->
<Button
x:Name="SubmitButton"
Text="Submit"
Command="{Binding FormCommand}">

调整完成后所有动态Entry的输入内容会实时同步到ViewModel的集合中,提交命令也可以正常触发,两个问题同步解决。

内容的提问来源于stack exchange,提问作者Stavrogin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 15:06:04