将多个 MvxSpinner 绑定到一个 ICommand

Binding Multiple MvxSpinner to a ICommand

我正在以编程方式创建不同数量的 MvxSpinners。无法预先确定生成的 MvxSpinners 的数量。由用户输入决定。

我有一个List<Beneficiary>。每个 MvxSpinner 都用于更新集合中的每个 Beneficiary

由于我无法确定要生成的 MvxSpinner 的数量(对应集合中 Beneficiary 的数量),我只好用一个 ICommand 来处理所有 HandleSelectedItem event 的 MvxSpinners。

挑战

我无法根据用户单击的 MvxSpinner 确定要更新的 List<Beneficiary> 的索引。

一个例子

var BeneficiaryList=new List<Beneficiary>()

如果集合中有5个Beneficiary对象,将生成5个MvxSpinner。

如果用户选择要更新集合索引 2 的 MVXSpinner,我如何确定要更新的 Beneficary 的索引?

我试过的

 private IList<Beneficiary> _beneficiaryList;
    public IList<Beneficiary> BeneficiaryList
    {
        get { return _beneficiaryList; }
        set { _beneficiaryList= value; RaisePropertyChanged(() => BeneficiaryList); }
    }

 public ICommand UpdateBeneficiary=> new MvxCommand<Beneficiary>(item =>
    {
        //item is of type Beneficiary
        //But I do not know which index of BeneficiaryList to update
    });

非常感谢您的帮助。

您可能还需要一个 ICommand 列表,每个微调器一个。在你的视图模型中有这样的东西...

private IList<ICommand> _commands;
public IList<ICommand> Commands {
    get {
        if (_commands == null) {
            _commands = BeneficiaryList.Select(x => new MvxCommand<Beneficiary>(item => {
                ...
            }));
        }
        return _commands;
    }
}

然后像这样设置你的绑定(假设你有一个旋转器列表)

for (int i = 0; i < spinners.Count; i++) {
    var spinner = spinners[i];
    set.Bind (spinner).To(vm => vm.Commands[i]);
}

嗯,回答我自己的问题很有趣。

我所做的是给每个 Spinner 一个唯一的 ID,该 ID 对应于集合的索引。

我创建了一个名为 MvxSpinnerIndexer 的自定义 Spinner,扩展了 MvxSpinner(我真的不认为这很重要。您可以扩展 Spinner)。 MvxSpinnerIndexer 检索到 Id 和 SelectedItem 然后将两者放入 Dictionary

这是 MvxSpinnerIndexer

的来源
        public class MvxSpinnerIndexer : Spinner
        {
           public MvxSpinnerIndexer(Context context, IAttributeSet attrs)
            : this(
                context, attrs,
                new MvxAdapter(context)
                {
                    SimpleViewLayoutId = global::Android.Resource.Layout.SimpleDropDownItem1Line
                })
               { }

        public MvxSpinnerIndexer(Context context, IAttributeSet attrs, IMvxAdapter adapter)
            : base(context, attrs)
        {
            var itemTemplateId = MvxAttributeHelpers.ReadListItemTemplateId(context, attrs);
            var dropDownItemTemplateId = MvxAttributeHelpers.ReadDropDownListItemTemplateId(context, attrs);
            adapter.ItemTemplateId = itemTemplateId;
            adapter.DropDownItemTemplateId = dropDownItemTemplateId;
            Adapter = adapter;
            SetupHandleItemSelected();
        }

        public new IMvxAdapter Adapter
        {
            get { return base.Adapter as IMvxAdapter; }
            set
            {
                var existing = Adapter;
                if (existing == value)
                    return;

                if (existing != null && value != null)
                {
                    value.ItemsSource = existing.ItemsSource;
                    value.ItemTemplateId = existing.ItemTemplateId;
                }

                base.Adapter = value;
            }
        }

        [MvxSetToNullAfterBinding]
        public IEnumerable ItemsSource
        {
            get { return Adapter.ItemsSource; }
            set { Adapter.ItemsSource = value; }
        }

        public int ItemTemplateId
        {
            get { return Adapter.ItemTemplateId; }
            set { Adapter.ItemTemplateId = value; }
        }

        public int DropDownItemTemplateId
        {
            get { return Adapter.DropDownItemTemplateId; }
            set { Adapter.DropDownItemTemplateId = value; }
        }

        public ICommand HandleItemSelected { get; set; }
        public int ViewId { get; set; }

        private void SetupHandleItemSelected()
        {
            ItemSelected += (sender, args) =>
            {
                //sender.
                var control = (MvxSpinnerIndexer)sender;
                var controlId = control.Id;
                var position = args.Position;
                HandleSelected(position, controlId);
            };
        }

        protected virtual void HandleSelected(int position, int? controlId)
        {
            var item = Adapter.GetRawItem(position);
            var content = new Dictionary<string, object> {{"Index", controlId}, {"SelectedItem", item}};

            //var param = new ListItemWithIndexModel { Index = controlId, SelectedItem = item };
            if (HandleItemSelected == null
                || item == null
                || !HandleItemSelected.CanExecute(content))
                return;

            HandleItemSelected.Execute(content);
        }
    }

在您的 ViewModel 中

public ICommand SpinnerSelected => new MvxCommand<Dictionary<string, object>>(item =>
    {
        var selectedItem = item["SelectedItem"] as ListItemModel;//Cast to the actual model
        var index = item["Index"] as int?;//The index of the collection to update

    });

我相信这会对社区有用。