将多个 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
});
我相信这会对社区有用。
我正在以编程方式创建不同数量的 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
});
我相信这会对社区有用。