在我们的应用程序中,我们使用ReactiveUI来遵循MVVM模式。在一个视图中,我们想要显示一个UITableView。数据通常传递给UITableView.Source但是使用ReactiveUI我们使用ReactiveTableViewSource<TSource>
。
我不明白的是我如何将我在ReactiveList
视图模型中获得的数据绑定到ReactiveTableViewSource
。
我们现在拥有的是我们在UIView中创建一个像这样的表:
Table = new UITableView(UIScreen.MainScreen.Bounds);
Table.Source = new TableSource(Table, MyReactiveList, (NSString) CellIdentifier, _cellHeight, cell => Debug.WriteLine(cell));
顺便说一句:用于什么的细胞动作?
此外,我们有一个Table源类,如下所示:
internal sealed class TableSource : ReactiveTableViewSource<MyListObject>
{
public TableSource(UITableView tableView, IReactiveNotifyCollectionChanged<MyListObject> collection, NSString cellKey, float sizeHint, Action<UITableViewCell> initializeCellAction = null) : base(tableView, collection, cellKey, sizeHint, initializeCellAction)
在我的视图模型中,我有一个更新我的ReactiveList的服务。它看起来像这样:
public sealed class MyService : ReactiveObject, IMyService
{
public IReactiveList<MyListObject> MyReactiveList { get; }
public async Task UpdateMyReactiveListAsync() {//...}
我在哪里将表源绑定到ReactiveList?我在哪里订阅活动?是否有我可能错过的任何文档或示例代码?
答案 0 :(得分:3)
使用ReactiveTableViewSource非常简单:
只需将List与您的UITableView
连接即可var tableView = new UITableView ();
// Bind the List agains the table view
// SampleObject is our model and SampleCell the cell
ViewModel.WhenAnyValue (vm => vm.Items).BindTo<SampleObject, SampleCell> (tableView, 46, cell => cell.Initialize());
然后创建一个自定义单元格,将模型数据与单元格绑定在一起。
public class SampleCell : ReactiveTableViewCell, IViewFor<SampleObject>
{
public SampleCell () : base() { }
public SampleCell (IntPtr handle) : base(handle) { }
private SampleObject _viewModel;
public SampleObject ViewModel
{
get { return _viewModel; }
set { this.RaiseAndSetIfChanged (ref _viewModel, value); }
}
object IViewFor.ViewModel
{
get { return ViewModel; }
set { ViewModel = value as SampleObject; }
}
public void Initialize()
{
this.WhenAnyValue (v => v.ViewModel.Name).BindTo (
this,
v => v.TextLabel.Text);
}
}
您可以在此处找到一个引人注目的示例:https://github.com/reicheltp/ReactiveTableViewSource-Sample
更新2016/03/09:最好在分离的Initialize方法中进行绑定,以防止多次调用。
如果您有更多问题,可以在Twitter上问我:@reicheltp
答案 1 :(得分:2)
要订阅事件,您可以指定UITableViewDelegateRx
var tvd = new UITableViewDelegateRx ();
Table.Delegate = tvd;
tvd.RowSelectedObs.Subscribe (c => { });
答案 2 :(得分:0)
仅使用ReactiveUI版本9.16.6进行一次小更新:
示例根据邮政编码列出了其中一些城市。
=>我的CityTableViewCell继承自ReactiveTableViewCell
public class CityViewModel : ReactiveObject
{
private ICityService CityService { get; }
private SourceCache<CityItemViewModel, int> _citiesCache;
private IObservable<IChangeSet<CityItemViewModel, int>> _citiesOperations => _citiesCache.Connect();
public readonly ReadOnlyObservableCollection<CityItemViewModel> Cities;
public CityViewModel(ICityService cityService)
{
CityService = cityService;
}
#region CityViewModelCommand
public ReactiveCommand<CityItemViewModel, Unit> CityClickCommand { get; }
#endregion
private async Task<IEnumerable<CityItemViewModel>> SearchCitiesAsync(string searchText, CancellationToken token)
{
IEnumerable<CityItemViewModel> items;
if (string.IsNullOrEmpty(searchText))
items = await CityService.ToListWithCountryCodeAsync(cancellationToken: token);
else
items = await CityService.ToListBySearchWithCountryCodeAsync(searchText, cancellationToken: token);
_citiesCache.Edit(innerList =>
{
innerList.Clear();
innerList.AddOrUpdate(items);
});
return items;
}
}
public class CityItemViewModel : ReactiveObject
{
public int Id { get; set; }
public string Name { get; set; }
public string PostalCode { get; set; }
public override string ToString()
=> $"[CityItemViewModel: Id={Id}, Name={Name}, PostalCode={PostalCode}]";
public CityItemViewModel() : base()
{
}
}
在我的ViewController的ViewDidLoad方法中:
this.WhenActivated((cleanup) =>
{
this.Bind(ViewModel,
x => x.SearchText,
x => x.searchBar.Text)
.DisposeWith(cleanup);
this.WhenAnyValue(v => v.ViewModel.Cities)
.BindTo<CityItemViewModel, CityTableViewCell>(tableView, CityTableViewCell.Key, 50, cell => cell.Initialize(),
source => source.ElementSelected.InvokeCommand(ViewModel.CityClickCommand))
.DisposeWith(cleanup);
});
在我的UITableViewCell的Initialize方法中:
public void Initialize()
{
this.WhenAnyValue(v => v.ViewModel.Name)
.Subscribe(name => cityLabel.Text = name);
this.WhenAnyValue(v => v.ViewModel.PostalCode)
.Subscribe(x => postalCodeLabel.Text = x);
}
希望可以帮助某人;)