gpt4 book ai didi

c# - 使用 Mvvmcross 进行 UITableView 分组的现代方法

转载 作者:太空宇宙 更新时间:2023-11-03 19:51:25 26 4
gpt4 key购买 nike

我发现了几种(不是太多)不同的方法来在 Xamarin+mvvmcross 中对单元格进行分组。我已经尝试了几个,但我遇到了一个问题:当我的真实服务返回更新的集合(有一个小的延迟)时,绑定(bind)并没有真正起作用并且列表仍然是空的。如果要运行假服务,它会立即返回结果,列表中会填满数据。

我尝试了几种方法,但没有人插入我前进,所以我不确定是否需要任何代码。只是询问是否有现代分组实现的示例/提示。

编辑:这是一个代码示例。当前版本基于 Stuart 的回答:Unable to bind to ios table section cells in mvvmcross, child cells bind as expected

View 模型:

    public override async void OnShow()
{
var calendarList = await DataService.GetListAsync();

CalendarList = new List<Model>(calendarList.OrderBy(a => a.Date));
}

因此,viewmodel 获取模型列表,按日期排序并将其设置为 CalendarList。 CalendarList 只是一个抛出通知的列表(new 正在做这个工作)。

查看,初始化:

    public override void ViewDidLoad()
{
base.ViewDidLoad();

var source = new TableSource(CalendarList);

this.AddBindings(new Dictionary<object, string>
{
{source, "ItemsSource CalendarList" }
});

CalendarList.Source = source;
CalendarList.ReloadData();
}

View 、表源

    public class TableSource : MvxSimpleTableViewSource
{
private static readonly NSString CalendarCellIdentifier = new NSString("CalendarCell");
private List<IGrouping<DateTime, Model>> GroupedCalendarList;

public TableSource(UITableView calendarView) : base(calendarView, "CalendarCell", "CalendarCell")
{
}


public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var foo = GroupedCalendarList[indexPath.Section].ToList();
var item = foo[indexPath.Row];

var cell = GetOrCreateCellFor(tableView, indexPath, item);

var bindable = cell as IMvxDataConsumer;
if (bindable != null)
bindable.DataContext = item;

return cell;
}

public override nint RowsInSection(UITableView tableview, nint section)
{
var numberRows = GroupedCalendarList[(int)section].Count();
return numberRows;
}

public override UIView GetViewForHeader(UITableView tableView, nint section)
{
var label = new UILabel();
label.Text = GroupedCalendarList[(int)section].FirstOrDefault().ScheduledStart.Value.Date.ToString();
label.TextAlignment = UITextAlignment.Center;

return label;
}

public override nint NumberOfSections(UITableView tableView)
{
return GroupedCalendarList.Count;
}

public override void ReloadTableData()
{
if (ItemsSource == null) return;
var calendarList = new List<Model>(ItemsSource as List<ActivityModel>);

List<IGrouping<DateTime, Model>> groupedCalendarList = calendarList.GroupBy(cl => cl.ScheduledStart.Value.Date).ToList();

if (ItemsSource != null)
GroupedCalendarList = new List<IGrouping<DateTime, Model>>(groupedCalendarList);
}
}

症状之一是在 VM 更新列表时没有调用 ReloadTableData()。

编辑 2:好吧,我尝试使用 ObservableCollection,我看到调用了 ReloadTableData,但 UI 仍然是空的。如果有人可以提供工作示例 - 那就太好了。

更新的虚拟机:

    public override async void OnShow()
{
var calendarList = await DataService.GetListAsync();

CalendarList.Clear();
foreach (var item in calendarList.OrderBy(a => a.ScheduledStart.Value.Date))
{
CalendarList.Add(item); // Lets bruteforce and send notification on each add. In real life it's better to use extension ObservableCollection.AddRange().
}
}

更新 View :

public override void ReloadTableData()
{
if (ItemsSource == null) return;
var calendarList = ItemsSource as IEnumerable<Model>;

var groupedCalendarList = calendarList.GroupBy(cl => cl.ScheduledStart.Value.Date).ToList();

GroupedCalendarList = new List<IGrouping<DateTime, Model>>(groupedCalendarList);

Mvx.Trace("Trying to add new item " + calendarList.Count());
}

在那种情况下,输出是满的

Diagnostic: 9.54 Trying to add new item 77

但 UI 列表仍然是空的。

EDIT3:如果用添加 Task.Run().Wait() 替换 VM.OnShow();到 VM 的 ctor(因此它会延迟 View.ViewDidLoad() 直到加载数据)- 然后列表正确显示。

public ViewModel()
{
Task.Run(async () =>
{
var calendarList = await DataService.GetListAsync();
CalendarList = new ObservableCollection<ActivityModel>(calendarList);
}).Wait(); // This guy is called before View.ViewDidLoad() and grouped list is shown properly
}

最佳答案

这里可能有很多问题。

  1. 我不建议像您那样进行绑定(bind)。而是创建一个绑定(bind)集并使用:

var set = this.CreateBindingSet<TClass, TViewModel>();
set.Bind(source).To(vm => vm.Collection);
set.Apply();

  1. 使用可观察集合,然后当您完成添加到可观察集合调用时: RaisePropertyChanged(() => Collection);

  2. 为了更轻松地对数据进行分组,我覆盖了 ItemsSource 以将数据推送到一个值字典和一个键数组中,以便更容易地计算出这些部分。

  3. 因为您只想提供文本,只需覆盖 TitleForHeader: public override string TitleForHeader(UITableView tableView, nint section)

关于c# - 使用 Mvvmcross 进行 UITableView 分组的现代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38861729/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com