振作起来……MonoMac 中与级别无关的 NSOutlineView!
经过数百次谷歌搜索,并查看了 ObjC 和 C# 代码,我终于想出了如何去做!我会在这里发布我的解决方案,以防其他人需要它。
这可能是也可能不是最好的方法,但它对我有用。
第 1 步:在 Interface Builder 中,添加一个 NSOutlineView。向其中添加 2 列,并将它们的 Identifier 设置为colName
, 和colAge
。
此外,当您使用它时,请在表单中添加一个按钮。
第 2 步:为 NSOutlineView 创建一个插座 - 我之所以叫我的插座,是lvMain
因为我来自 VCL 背景。此外,为您的按钮创建一个操作(这将是 onClick 处理程序)。
第 3 步:保存您的 XIB 文件,然后返回 Mono - 它会更新您的项目文件。现在,我们要创建希望用于视图的模型。
对于这个例子,我将使用一个简单的 Person 对象:
public class Person:NSObject
{
public string Name {
get;
set;
}
public int Age {
get;
set;
}
public List<Person> Children {
get;
set;
}
public Person (string name, int age)
{
Name = name;
Age = age;
Children = new List<Person>();
}
}
那里没有什么太复杂的地方。
第 4 步:创建数据源。对于这个例子,这就是我所做的:
public class MyDataSource:NSOutlineViewDataSource
{
/// The list of persons (top level)
public List<Person> Persons {
get;
set;
}
// Constructor
public MyDataSource()
{
// Create the Persons list
Persons = new List<Person>();
}
public override int GetChildrenCount (NSOutlineView outlineView, NSObject item)
{
// If the item is not null, return the child count of our item
if(item != null)
return (item as Person).Children.Count;
// Its null, that means its asking for our root element count.
return Persons.Count();
}
public override NSObject GetObjectValue (NSOutlineView outlineView, NSTableColumn forTableColumn, NSObject byItem)
{
// Is it null? (It really shouldnt be...)
if (byItem != null) {
// Jackpot, typecast to our Person object
var p = ((Person)byItem);
// Get the table column identifier
var ident = forTableColumn.Identifier.ToString();
// We return the appropriate information for each column
if (ident == "colName") {
return (NSString)p.Name;
}
if (ident == "colAge") {
return (NSString)p.Age.ToString();
}
}
// Oh well.. errors dont have to be THAT depressing..
return (NSString)"Not enough jQuery";
}
public override NSObject GetChild (NSOutlineView outlineView, int childIndex, NSObject ofItem)
{
// If the item is null, it's asking for a root element. I had serious trouble figuring this out...
if(ofItem == null)
return Persons[childIndex];
// Return the child its asking for.
return (NSObject)((ofItem as Person).Children[childIndex]);
}
public override bool ItemExpandable (NSOutlineView outlineView, NSObject item)
{
// Straight forward - it wants to know if its expandable.
if(item == null)
return false;
return (item as Person).Children.Count > 0;
}
}
第 5 步 - 最好的一步:绑定数据源并添加虚拟数据!我们还想在每次添加新元素时刷新我们的视图。这可能可以优化,但我仍然在“哦,我的上帝它的工作”区域,所以我目前不在乎。
// Our Click Action
partial void btnClick (NSObject sender)
{
var p = new Person("John Doe",18);
p.Children.Add(new Person("Jane Doe",10));
var ds = lvMain.DataSource as MyDataSource;
ds.Persons.Add(p);
lvMain.ReloadData();
}
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
lvMain.DataSource = new MyDataSource();
}
我希望这些信息可以帮助像我这样的 MonoMac 新人的困扰。