将多个MvxSpinner绑定到ICommand

时间:2015-12-08 15:19:16

标签: c# android xamarin xamarin.android mvvmcross

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

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

由于我无法确定要生成的MvxSpinner的数量(对应于集合中Beneficiary的计数),因此我不得不让一个ICommand来处理所有{{1} MvxSpinners。

挑战

我很难确定要更新的HandleSelectedItem event的索引,具体取决于用户点击的MvxSpinner。

示例

List<Beneficiary>

如果集合中有5个var BeneficiaryList=new List<Beneficiary>() 对象,则会生成5个MvxSpinner。

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

我尝试了什么

Beneficary

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

您可能还需要一个ICommands列表,每个微调器一个。在您的视图模型中有类似的东西...

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]);
}

答案 1 :(得分:0)

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

我所做的是为每个Spinner提供一个与集合索引相对应的唯一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

    });

我相信这对社区有用。