我正在尝试设置一个项目表(UITableView),每个单元格中都有一个按钮,可以导航到其项目的详细配置文件。
但我不确定 MvvmCross 中正确的方法是什么。我的一些想法:
- 将
ItemCellView
的按钮导出公开为公共(public),并将其绑定(bind)到GetOrCreateCellFor
- 将
ShowItemDetailsCommand
传递到每个ItemCellView
中并将其绑定(bind)到那里 - 使用从
ItemCellView
到ItemsView
的简单回调,而不是绑定(bind) - 为每个单元格获取单独的
MvxViewModel
并从那里调用导航服务
public class Item
{
public string Name { get; set; }
}
public class ItemsViewModel : MvxViewModel
{
public List<Item> Items { get; }
public MvxCommand ShowItemDetailsCommand { get; }
readonly IMvxNavigationService _navigationService;
readonly IDatabaseService _databaseService;
public ItemsViewModel(IMvxNavigationService navigationService, IDatabaseService databaseService)
{
ShowItemDetailsCommand = new MvxCommand(ShowItemDetails);
_navigationService = navigationService;
_databaseService = databaseService;
Items = _databaseService.SelectItems();
}
void ShowItemDetails()
{
// not sure how "item" gets here so far
_navigationService.Navigate<ItemDetailsViewModel, Item>(item);
}
}
public partial class ItemsView : MvxTableViewController<ItemsViewModel>
{
public ItemsView() : base("ItemsView", null) {}
public override void ViewDidLoad()
{
base.ViewDidLoad();
TableView = View as UITableView;
var source = new TableViewSource(TableView);
var bindings = this.CreateBindingSet<ItemsView, ItemsViewModel>();
bindings.Bind(source).To(vm => vm.Items);
bindings.Apply();
TableView.Source = source;
TableView.ReloadData();
}
public class TableViewSource : MvxTableViewSource
{
public TableViewSource(UITableView tableView) : base(tableView)
{
TableView.RegisterNibForCellReuse(UINib.FromName("ItemCellView", NSBundle.MainBundle), ItemCellView.kCellId);
}
protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
{
return TableView.DequeueReusableCell(ItemCellView.kCellId, indexPath) as ItemCellView;
}
}
}
public partial class ItemCellView : MvxTableViewCell
{
public const string kCellId = "item_cell";
// also has an [Outlet] UIButton in the .designer.cs part
public ItemCellView(IntPtr handle) : base(handle)
{
this.DelayBind(() =>
{
var bindings = this.CreateBindingSet<ItemCellView, Item>();
bindings.Bind(Name).To(i => i.Name);
bindings.Apply();
});
}
}
最佳答案
您应该在单元格的构造方法中绑定(bind) ItemCellView
的按钮:
// MyBtn is my Cell's button outlet
protected ItemCellView(IntPtr handle) : base(handle)
{
this.DelayBind(() =>
{
var bindings = this.CreateBindingSet<MyTableViewCell, Item>();
// Use this bind to set your button's title
bindings.Bind(MyBtn).For("Title").To(item => item.Name);
// This bind is used for binding a command in the Item model
// CommandParameter can pass your parameter
bindings.Bind(MyBtn).To(item => item.ShowItemDetailsCommand).CommandParameter(DataContext);
bindings.Apply();
});
}
由于单元格中的 DataContext 已更改为您的 Item
模型,因此应在模型类中配置绑定(bind)命令:
public class Item
{
private readonly Lazy<IMvxNavigationService> _navigationService = new Lazy<IMvxNavigationService>(Mvx.Resolve<IMvxNavigationService>);
public string Name { set; get; }
private ICommand showItemDetailsCommand;
public ICommand ShowItemDetailsCommand
{
get
{
return showItemDetailsCommand ?? (showItemDetailsCommand = new MvxCommand<Item>(ShowItemDetails));
}
}
async void ShowItemDetails(Item item)
{
await _navigationService.Value.Navigate<SecondViewModel, Item>(item);
}
}
最后你要推送的SecondViewModel会通过事件Prepare()
接收到这个参数:
public class SecondViewModel : MvxViewModel<Item>
{
public override void Prepare(Item parameter)
{
}
}
关于xamarin.ios - 将命令绑定(bind)到 MvvmCross 中表格单元格内的按钮的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50472755/