6

2 つの列を持つ単純な NSOutlineView と、1 レベル以上の深さ (階層) のデータ構造を作成する方法がわかりません。

私はこれを何日も調査してきましたが、私が見つけることができるのはObjective Cの例だけで、実際には何にも使用できません.

これを行うにはさまざまなパターンがあることを理解しています.1つはDataSourceパターンです。NSOutlineViewDataSource から継承したクラスを作成しようとしましたが、これだけで、次に何をすべきかわかりません。

NSOutlineView に次のクラスを表示したいとしましょう。

public class Person
{
    public string Name {get;set;} // First column
    public int Age {get;set} // Second column
    public List<Person> Children {get;set} // Children
}

これを達成するための最も簡単なアプローチは何でしょうか?

4

2 に答える 2

14

気を取り直して... MonoMac のレベルに依存しない NSOutlineView!

何百もの Google 検索を行い、ObjC と C# コードを調べた結果、ついにその方法を見つけました。他の誰かがそれを必要とする場合に備えて、ここに私の解決策を投稿します。

これが最善の方法である場合とそうでない場合がありますが、私にとってはうまくいきます。


ステップ 1 : Interface Builder で、NSOutlineView を追加します。それに 2 つの列を追加し、それらの識別子を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 初心者の悩みを抱えた魂の助けになれば幸いです。

于 2012-09-20T17:32:37.353 に答える
2

これを追跡するのに少し時間がかかりましたが、Xamarin にはこれを行う方法の例があります

于 2014-01-14T01:44:26.427 に答える