我想要达到的目标是这样的:
DevExpress Grid
Table with fixed columns
上述链接中的表格可以包含“固定”列,不会与其他内容一起滚动。
我知道NSTableView
的{{1}}功能和floatsGroupRows
的{{1}}方法;但要实现上述目标,这还不够:
NSScrollView
s,首先是addFloatingSubview:forAxis:
下的2个单独的NSView
中(这是NSClipView
的默认操作)所以很久以来我找不到任何内置的解决方案。我唯一的想法是彼此相邻使用3 NSScrollView
s(左侧+1,右侧+1);并手动同步它们中的垂直滚动。如何同步水平滚动,现在这是一个更难的问题。左侧和右侧不应滚动,因此应“浮动”。 对于表格的内容,(*);但是列标题是不同的动物。好吧,仍然应该有办法通过黑客绘制列来实现这种浮动行为...... NSTableView
的{{1}}方法应该适用于IMO
但是,我还没有开始实现上面的那个,因为我的NSTableView
已经足够缓慢(NSTableview View Based Scrolling Performance)了,而且我确信这些加上的东西会让它慢下来。 / p>
有没有人(更好)知道如何在Cocoa中实现浮动列? 任何帮助非常感谢!
修改
(*):NSScrollView
的{{1}}不起作用。正如我现在所看到的,如果给予此方法的addFloatingSubview:forAxis:
是NSTableView
的子视图,则会得到特殊处理。该表可能会添加自己的逻辑;现在对我来说,NSScrollView
一次只能有一个浮动行。
答案 0 :(得分:1)
我已经实现了垂直同步两个NSTableViews。不清楚为什么你需要三个,但无论如何。请注意,这是使用Xamarin.Mac lib的所有c#代码。这些是本机Cocoa平台上的包装器。您必须自己将此转换为obj c / swift。这应该不难。
从笔尖醒来:
table1.EnclosingScrollView.ContentView.PostsBoundsChangedNotifications = true;
NSNotificationCenter.DefaultCenter.AddObserver (NSView.BoundsChangedNotification, BoundsDidChangeNotification, table1.EnclosingScrollView.ContentView);
table2.EnclosingScrollView.ContentView.PostsBoundsChangedNotifications = true;
NSNotificationCenter.DefaultCenter.AddObserver (NSView.BoundsChangedNotification, BoundsDidChangeNotification, table2.EnclosingScrollView.ContentView);
因此,每当其中一个表滚动时,就会调用BoundsDidChangeNotification,并负责同步y轴。请注意,即使由于惯性滚动或边界的程序更改(或放大/缩小或调整视图大小等)而发生滚动时,此功能仍然有效。此类事件可能并不总是触发专门用于“用户滚动”的事件,因此,这是更好的方法。 Bellow是BoundsDidChangeNotification方法:
public void BoundsDidChangeNotification (NSNotification o)
{
if (o.Object == table1.EnclosingScrollView.ContentView) {
var bounds = new CGRect (new CGPoint (table2.EnclosingScrollView.ContentView.Bounds.Left, table1.EnclosingScrollView.ContentView.Bounds.Top), table2.EnclosingScrollView.ContentView.Bounds.Size);
if (bounds == table2.EnclosingScrollView.ContentView.Bounds)
return;
table2.ScrollPoint (bounds.Location);
} else {
var bounds = new CGRect (new CGPoint(table1.EnclosingScrollView.ContentView.Bounds.Left, table2.EnclosingScrollView.ContentView.Bounds.Top), table1.EnclosingScrollView.ContentView.Bounds.Size);
if (table1.EnclosingScrollView.ContentView.Bounds == bounds)
return;
table1.ScrollPoint (bounds.Location);
}
}
这里没什么太花哨的......有一些边界相等检查以避免最终的无限循环(table1告诉table2同步然后table2 tels table1等等,永远)。 AFAI记得,如果你ScrollPoint到当前的滚动位置,边界确实没有被触发,但是因为否则会发生无限循环,我认为额外的检查是值得的 - 你永远不会知道未来的os x版本会发生什么。 / p>