我正在使用NSTableView创建树形视图,而不使用NSOutlineView,因为Xamarin中存在一些技术上的不足,无法将OutlineView用于ReactUI。
我面临的问题是,当我扩展节点时,其视图高度应该增加。但是高度已经在RowHeight
方法中计算了,并且视图在`GetOrCreateSubView中绘制,因此就像Hen-Egg问题一样。当子节点包含更多级别时,问题会加剧。每当我需要计算高度时,如下所示:
public override nfloat GetRowHeight(NSTableView tableView, nint row)
{
var item = Items[(int)row];
int rowHeight = 30;
//recursively find if child are expanded
if (item.IsExpanded)
{
rowHeight *= item.Children.Count;
foreach (FolderViewModel vm in item.Children)
{
rowHeight *= GetChildrenCount(vm);
}
rowHeight += 30; // +30 for top level itself.
}
return rowHeight;
}
private int GetChildrenCount(FolderViewModel vm)
{
return vm.IsExpanded ? vm.Children.Count : 1;
}
在Items
之外创建子视图节点时,我正在添加子视图,但最后将其添加。我希望将其添加到扩展节点的正下方。
public override NSView GetViewForItem(NSTableView tableView,
NSTableColumn tableColumn, nint row)
{
var item = Items[(int)row];
var view = tableView.MakeView("selectiveSyncCell", _tableView);
int rowHeight = 30;
if (item.IsExpanded)
{
rowHeight *= item.Children.Count;
}
view = view ?? new SelectiveSyncListCellView(
new CGRect(0, 0, _tableView.Frame.Width, rowHeight),
item,
this);
if(item.IsExpanded)
{
int counter = 0;
foreach(FolderViewModel node in item.Children){
counter++;
view.AddSubview(GetOrCreateSubViewFor(view,node,counter));
}
}
view.Display();
return view;
}
private NSView GetOrCreateSubViewFor(NSView view, FolderViewModel node, int count)
{
var subview = new SelectiveSyncListCellView(
new CGRect(0, count * 30, view.Frame.Width, 30),
node,
this);
if (node.IsExpanded && node.Children.Any())
{
int counter = count;
foreach (FolderViewModel subnode in node.Children)
{
subview.AddSubview(GetOrCreateSubViewFor(subview, subnode, ++counter));
}
subview.Display();
}
return subview;
}
外观如下:
-- A
-- A1
-- A2
-- A1.1
-- A1.2
-- B
-- C
实际上A1.1
和A1.2
应该低于A1
。
我应该创建一个cellview数组来保存所有内容并重绘它吗? 我应该使用自动排版吗? 是实现这一目标的另一种方法吗?