2

我正在尝试StackPanel在我的 MonoMac 项目中实现一个垂直等效项,但无法弄清楚。我没有使用界面生成器,而是以编程方式创建控件(这是一个限制)。我尝试使用 aCollectionView但该控件中的所有项目的大小都相同。

环顾互联网,这似乎NSTableView是要走的路,但我不知道该怎么做,尤其是在使用 MonoMac 目标时使用 C#。允许我创建我想要渲染的视图CollectionView更直接一些。CollectionViewItem.ItemPrototype但是对于NSTableView,似乎我只能指定一个返回NSObject要显示的 s 的数据源。我如何获取这些数据,然后将它们绑定到我想要粘贴在那里的视图?

我更喜欢 C# 代码,但我正处于接受任何和所有帮助的阶段!

4

1 回答 1

3

我终于能够让它工作了。这里有一些代码供任何想尝试的人使用。基本上,我们需要NSTableViewDelegate为所需的功能编写 s。此实现也不会缓存控件或任何东西。Cocoa API 文档中提到了使用标识符来重用控件或其他东西,但标识符字段在 MonoMac 中是 get-only。

我还最终NSTableViewDelegate在我的数据源本身中实现了我的函数,我确信这根本不是 kosher,但我不确定最佳实践是什么。

这是数据源类:

class MyTableViewDataSource : NSTableViewDataSource
{
    private NSObject[] _data;

    // I'm coming from an NSCollectionView, so my data is already in this format
    public MyTableViewDataSource(NSObject[] data)
    {
        _data = data;
    }

    public override int GetRowCount(NSTableView tableView)
    {
        return _data.Length;
    }

    #region NSTableViewDelegate Methods

    public NSView GetViewForItem(NSTableView tableView, NSTableColumn tableColumn, int row)
    {
        // MyViewClass extends NSView
        MyViewClass result = tableView.MakeView("MyView", this) as MyViewClass;
        if (result == null)
        { 
            result = new MyViewClass(_data[row]);
            result.Frame = new RectangleF(0, 0, tableView.Frame.Width, 100); // height doesn't matter since that is managed by GetRowHeight
            result.NeedsDisplay = true;
            // result.Identifier = "MyView"; // this line doesn't work because Identifier only has a getter
        }

        return result;
    }

    public float GetRowHeight(NSTableView tableView, int row)
    {
        float height = FigureOutHeightFromData(_data[row]); // run whatever algorithm you need to get the row's height
        return height;
    }

    #endregion
}

这是以编程方式创建表的片段:

var tableView = new NSTableView();
var dataSource = new MyTableViewDataSource();

tableView.DataSource = dataSource;
tableView.HeaderView = null; // get rid of header row
tableView.GetViewForItem = dataSource.GetViewForItem;
tableView.GetRowHeight = dataSource.GetRowHeight;

AddSubView(tableView);

因此,它并不完美StackPanel,因为需要手动计算行高,但总比没有好。

于 2012-12-20T16:08:34.297 回答