1

我想要实现的是这样的:
DevExpress Grid
Table with fixed columns

上述链接中的表格可以有“固定”列,不随其他内容滚动。

我知道NSTableView' 的功能floatsGroupRows和方法;但要实现上述目标,这些还不够:NSScrollViewaddFloatingSubview:forAxis:

  • 列不是NSViews,首先
  • 表头和表内容放在下面的2个单独NSClipView的s中NSScrollView(这是默认操作NSTableView

所以只要我找不到任何内置的解决方案。我唯一的想法是NSTableView彼此相邻使用 3 秒(左侧为 +1,右侧为 +1);并手动同步其中的垂直滚动。如何同步水平滚动,现在这是一个更难的问题。左右两侧不应该滚动,所以应该“浮动”。对于表格的内容,NSScrollView'addFloatingSubview:forAxis:方法应该适用于 IMO(*);但列标题是不同的动物。好的,仍然应该有一种方法可以通过破解列的绘图来实现这种浮动行为......

但是,我仍然没有开始实现上面的那个,因为我NSTableView的速度已经足够慢了(基于 NSTableview 视图的滚动性能),而且我确信这些加上一些东西会大大减慢它。

有没有人(更好的)想法如何在 Cocoa 中实现浮动列?非常感谢任何帮助!

编辑

(*): NSScrollView'saddFloatingSubview:forAxis:不适用于此。正如我现在所看到的,如果NSView给定此方法是 an 的子视图NSTableView,它会得到特殊处理。可能该表将自己的逻辑添加到;现在对我来说结果是,NSTableView一次只能有 1 个浮动行。

4

1 回答 1

1

我已经实现了两个 NSTableView 的垂直同步。不太清楚为什么你需要三个,但无论如何。请注意,这是使用 Xamarin.Mac 库的所有 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 到当前滚动的位置,不会触发 bounds 的变化,但是由于否则会发生无限循环,我认为额外的检查是值得的——你永远不知道在未来的 os x 版本中会发生什么。

于 2016-01-22T11:41:47.103 回答