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

如何将可搜索TableView改造为输入组件?

把可搜索TableView改造为输入选择组件(MvvmCross实现)

首先咱们得明确核心目标:把这个原本用来展示数据、跳转详情的TableView,改成能选择条目并返回数据给父输入视图的下拉选择组件。结合你用的MvvmCross框架,下面给你一步步拆解改造方案:


1. 调整ViewModel,支持返回选中结果

MvvmCross自带的CloseAsync方法是最贴合MVVM架构的返回结果方式,咱们可以基于这个来改造你的CMCTableViewModel:

public class CMCTableViewModel : MvxViewModel
{
    protected readonly ICoinMarketCapService _coinMarketCapService;
    // 新增:存储选中的条目,用于返回给父视图
    private CoinModel _selectedCoin;
    public CoinModel SelectedCoin
    {
        get => _selectedCoin;
        set => SetProperty(ref _selectedCoin, value);
    }

    // 新增:选择条目的命令,触发后返回结果并关闭当前页面
    public ICommand SelectCoinCommand => new MvxCommand<CoinModel>(async (coin) =>
    {
        if (coin == null) return;
        SelectedCoin = coin;
        // 通过MvvmCross的Close方法把选中项传递给父ViewModel
        await CloseAsync(SelectedCoin);
    });

    public CMCTableViewModel(ICoinMarketCapService coinMarketCapService)
    {
        _coinMarketCapService = coinMarketCapService;
        // 保留你原来的搜索、数据填充逻辑
        LoadCoinData();
    }

    // 保留你已实现的搜索、数据加载方法(比如LoadCoinData、SearchCommand等)
    private async void LoadCoinData()
    {
        // 你的原有数据加载代码
    }
}

2. 修改TableView交互,绑定选择命令

把原来跳转详情页的逻辑,替换成绑定到新增的SelectCoinCommand:

iOS端(TableViewSource示例)

protected override void BindCell(MvxListItemView cell, object dataContext)
{
    base.BindCell(cell, dataContext);
    var coin = dataContext as CoinModel;
    // 移除原跳转逻辑,绑定点击事件到选择命令
    var bindingSet = this.CreateBindingSet<YourCoinCell, CoinModel>();
    bindingSet.Bind(cell).For(v => v.BindingClick()).To(vm => vm.SelectCoinCommand).CommandParameter(coin);
    bindingSet.Apply();
}

Android端(RecyclerView.Adapter示例)

public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
    var coin = _coinList[position];
    var viewHolder = holder as CoinViewHolder;
    // 绑定条目点击到选择命令
    var bindingSet = this.CreateBindingSet<CoinViewHolder, CoinModel>();
    bindingSet.Bind(viewHolder.ItemView).For("Click").To(vm => vm.SelectCoinCommand).CommandParameter(coin);
    bindingSet.Apply();
}

3. 在父输入视图中打开选择器并接收结果

你的父ViewModel需要触发打开选择器的操作,并且监听返回的选中项,把数据填充到输入框:

public class ParentInputViewModel : MvxViewModel
{
    private string _selectedCoinName;
    // 绑定到输入框的属性
    public string SelectedCoinName
    {
        get => _selectedCoinName;
        set => SetProperty(ref _selectedCoinName, value);
    }

    // 打开选择器的命令(绑定到输入框的点击或下拉按钮)
    public ICommand OpenCoinSelectorCommand => new MvxAsyncCommand(async () =>
    {
        // 打开CMCTableViewModel,等待返回选中的硬币数据
        var selectedCoin = await NavigationService.Navigate<CMCTableViewModel, CoinModel>();
        if (selectedCoin != null)
        {
            // 把选中的硬币名称填充到输入框
            SelectedCoinName = selectedCoin.Name;
            // 如需其他字段(如Symbol、ID),可在这里继续处理
        }
    });
}

4. 优化输入选择体验(可选)

为了更贴近输入组件的使用习惯,可以做这些优化:

  • 让搜索框自动获取焦点,打开选择器后直接可输入
  • 保留实时搜索过滤的逻辑,提升选择效率
  • 添加「取消」按钮,点击后关闭选择器不返回任何结果

关键注意点

  • 确保CoinModel是简单的POCO类(可序列化),MvvmCross才能顺利传递它
  • 如果原来的TableView需要兼顾「独立展示」和「选择器」两种模式,可以给ViewModel加一个IsSelectorMode的参数,根据参数切换逻辑
  • 不想用CloseAsync的话,也可以用MvxMessenger发送消息,父ViewModel订阅消息接收选中项,但Close机制更适合这种场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:54:18