将单元格绑定到字典<string, List<object>>
Binding Cell to Dictionary<string, List<object>>
我 运行 遇到了一个奇怪的问题,我不确定如何解决。在我的 iOS 项目中,我有我的 TableViewCell 和 TableSource,我的 TableSource 应该用如下信息填充每个单元格:
private Dictionary<string, List<Item>> savedItemList;
protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
{
//var foo = savedItemList.ElementAt(indexPath.Section).Value;
//var Item = foo[indexPath.Row];
NSString cellIdentifier;
cellIdentifier = CellsIdentifier.Key;
var cell = (MyTableViewCell)TableView.DequeueReusableCell(cellIdentifier, indexPath);
return cell;
}
public override nint NumberOfSections(UITableView tableView)
{
return savedItemList.Count;
}
public override string TitleForHeader(UITableView tableView, nint section)
{
return savedItemList.Keys.ElementAt((int)section);
}
到目前为止,headers 和一切都没有问题,但我不确定如何从单元格内部实际绑定数据。目前我有
public partial class MyTableViewCell : MvxTableViewCell
{
public static readonly NSString Key = new NSString("MyTableViewCell");
public static readonly UINib Nib;
protected MyTableViewCell(IntPtr handle) : base(handle)
{
SelectionStyle = UITableViewCellSelectionStyle.None;
this.DelayBind(() =>
{
var set = this.CreateBindingSet<MyTableViewCell, Item>();
set.Bind(LBL_NAME)
.To(item => item.Name)
.Apply();
});
// Note: this .ctor should not contain any initialization logic.
}
}
但是当我加载该视图时,我收到:
MvxBind:Warning: 8.03 Unable to bind: source property source not found Property:Name on KeyValuePair`2
MvxBind:Warning: 8.03 Unable to bind: source property source not found Property:Name on KeyValuePair`2
剩下的是默认标签文本。我该如何设置绑定以从字典读取数据?
您是如何配置 ViewModel 的?您应该将 TableView.Source
的 ItemsSource 绑定到您的 ViewModel,然后在那里设置您的数据:
这是我在视图中的绑定代码:
var source = new TableSource(TableView);
TableView.Source = source;
TableView.RowHeight = 120f;
TableView.ReloadData();
var set = this.CreateBindingSet<FirstView, FirstViewModel>();
set.Bind(source).For(s => s.ItemsSource).To(vm => vm.ItemsGroup);
set.Apply();
ViewModel可能是这样的:
public class FirstViewModel : MvxViewModel
{
public FirstViewModel()
{
// Emulate three groups here.
ItemsGroup = new List<SessionGroup>();
for (int i=0; i<3; i++)
{
var list = new List<Item>();
for (int j=0; j<10; j++)
{
list.Add(new Item { Name = "Section:" + i + "Item" + j });
}
ItemsGroup.Add(new SessionGroup("section" + i, list));
}
}
private List<SessionGroup> _ItemsGroup;
public List<SessionGroup> ItemsGroup
{
get
{
return _ItemsGroup;
}
set
{
_ItemsGroup = value;
RaisePropertyChanged(() => ItemsGroup);
}
}
}
public class Item
{
public string Name { set; get; }
}
public class SessionGroup : List<Item>
{
public string Key { get; set; }
public SessionGroup(string key, List<Item> items) : base(items)
{
Key = key;
}
}
绑定完成后,我们就可以呈现TableView了。这是我的 MvxTableViewSource
:
public class TableSource : MvxTableViewSource
{
private static readonly NSString CellIdentifier = new NSString("MyTableViewCell");
public TableSource(UITableView tableView)
: base(tableView)
{
tableView.SeparatorStyle = UITableViewCellSeparatorStyle.None;
tableView.RegisterNibForCellReuse(UINib.FromName("MyTableViewCell", NSBundle.MainBundle),
CellIdentifier);
}
protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
{
return TableView.DequeueReusableCell(CellIdentifier, indexPath);
}
protected override object GetItemAt(NSIndexPath indexPath)
{
var _sessionGroup = ItemsSource.ElementAt(indexPath.Section) as SessionGroup;
if (_sessionGroup == null)
return null;
return _sessionGroup[indexPath.Row];
}
public override nint NumberOfSections(UITableView tableView)
{
return ItemsSource.Count();
}
public override nint RowsInSection(UITableView tableview, nint section)
{
var group = ItemsSource.ElementAt((int)section) as SessionGroup;
return group.Count();
}
public override string TitleForHeader(UITableView tableView, nint section)
{
var group = ItemsSource.ElementAt((int)section) as SessionGroup;
return string.Format($"Header for section {group.Key}");
}
}
更新:
如果您想将 ItemsSource
绑定到 Dictionary<>
,只需修改 GetItemAt()
事件:
protected override object GetItemAt(NSIndexPath indexPath)
{
return savedItemList.Values.ToList()[indexPath.Section][indexPath.Row];
}
public override nint NumberOfSections(UITableView tableView)
{
if (ItemsSource != null)
{
savedItemList = (Dictionary<string, List<Item>>)ItemsSource;
return savedItemList.Count();
}
return 0;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
if (ItemsSource != null)
{
savedItemList = (Dictionary<string, List<Item>>)ItemsSource;
return savedItemList.Values.ToList()[(int)section].Count;
}
return 0;
}
指出将在单元格class中使用的模型。
我也更新了demo,请查收
我 运行 遇到了一个奇怪的问题,我不确定如何解决。在我的 iOS 项目中,我有我的 TableViewCell 和 TableSource,我的 TableSource 应该用如下信息填充每个单元格:
private Dictionary<string, List<Item>> savedItemList;
protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
{
//var foo = savedItemList.ElementAt(indexPath.Section).Value;
//var Item = foo[indexPath.Row];
NSString cellIdentifier;
cellIdentifier = CellsIdentifier.Key;
var cell = (MyTableViewCell)TableView.DequeueReusableCell(cellIdentifier, indexPath);
return cell;
}
public override nint NumberOfSections(UITableView tableView)
{
return savedItemList.Count;
}
public override string TitleForHeader(UITableView tableView, nint section)
{
return savedItemList.Keys.ElementAt((int)section);
}
到目前为止,headers 和一切都没有问题,但我不确定如何从单元格内部实际绑定数据。目前我有
public partial class MyTableViewCell : MvxTableViewCell
{
public static readonly NSString Key = new NSString("MyTableViewCell");
public static readonly UINib Nib;
protected MyTableViewCell(IntPtr handle) : base(handle)
{
SelectionStyle = UITableViewCellSelectionStyle.None;
this.DelayBind(() =>
{
var set = this.CreateBindingSet<MyTableViewCell, Item>();
set.Bind(LBL_NAME)
.To(item => item.Name)
.Apply();
});
// Note: this .ctor should not contain any initialization logic.
}
}
但是当我加载该视图时,我收到:
MvxBind:Warning: 8.03 Unable to bind: source property source not found Property:Name on KeyValuePair`2
MvxBind:Warning: 8.03 Unable to bind: source property source not found Property:Name on KeyValuePair`2
剩下的是默认标签文本。我该如何设置绑定以从字典读取数据?
您是如何配置 ViewModel 的?您应该将 TableView.Source
的 ItemsSource 绑定到您的 ViewModel,然后在那里设置您的数据:
这是我在视图中的绑定代码:
var source = new TableSource(TableView);
TableView.Source = source;
TableView.RowHeight = 120f;
TableView.ReloadData();
var set = this.CreateBindingSet<FirstView, FirstViewModel>();
set.Bind(source).For(s => s.ItemsSource).To(vm => vm.ItemsGroup);
set.Apply();
ViewModel可能是这样的:
public class FirstViewModel : MvxViewModel
{
public FirstViewModel()
{
// Emulate three groups here.
ItemsGroup = new List<SessionGroup>();
for (int i=0; i<3; i++)
{
var list = new List<Item>();
for (int j=0; j<10; j++)
{
list.Add(new Item { Name = "Section:" + i + "Item" + j });
}
ItemsGroup.Add(new SessionGroup("section" + i, list));
}
}
private List<SessionGroup> _ItemsGroup;
public List<SessionGroup> ItemsGroup
{
get
{
return _ItemsGroup;
}
set
{
_ItemsGroup = value;
RaisePropertyChanged(() => ItemsGroup);
}
}
}
public class Item
{
public string Name { set; get; }
}
public class SessionGroup : List<Item>
{
public string Key { get; set; }
public SessionGroup(string key, List<Item> items) : base(items)
{
Key = key;
}
}
绑定完成后,我们就可以呈现TableView了。这是我的 MvxTableViewSource
:
public class TableSource : MvxTableViewSource
{
private static readonly NSString CellIdentifier = new NSString("MyTableViewCell");
public TableSource(UITableView tableView)
: base(tableView)
{
tableView.SeparatorStyle = UITableViewCellSeparatorStyle.None;
tableView.RegisterNibForCellReuse(UINib.FromName("MyTableViewCell", NSBundle.MainBundle),
CellIdentifier);
}
protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
{
return TableView.DequeueReusableCell(CellIdentifier, indexPath);
}
protected override object GetItemAt(NSIndexPath indexPath)
{
var _sessionGroup = ItemsSource.ElementAt(indexPath.Section) as SessionGroup;
if (_sessionGroup == null)
return null;
return _sessionGroup[indexPath.Row];
}
public override nint NumberOfSections(UITableView tableView)
{
return ItemsSource.Count();
}
public override nint RowsInSection(UITableView tableview, nint section)
{
var group = ItemsSource.ElementAt((int)section) as SessionGroup;
return group.Count();
}
public override string TitleForHeader(UITableView tableView, nint section)
{
var group = ItemsSource.ElementAt((int)section) as SessionGroup;
return string.Format($"Header for section {group.Key}");
}
}
更新:
如果您想将 ItemsSource
绑定到 Dictionary<>
,只需修改 GetItemAt()
事件:
protected override object GetItemAt(NSIndexPath indexPath)
{
return savedItemList.Values.ToList()[indexPath.Section][indexPath.Row];
}
public override nint NumberOfSections(UITableView tableView)
{
if (ItemsSource != null)
{
savedItemList = (Dictionary<string, List<Item>>)ItemsSource;
return savedItemList.Count();
}
return 0;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
if (ItemsSource != null)
{
savedItemList = (Dictionary<string, List<Item>>)ItemsSource;
return savedItemList.Values.ToList()[(int)section].Count;
}
return 0;
}
指出将在单元格class中使用的模型。
我也更新了demo,请查收