2

GTK# で TreeView を使用していますが、カスタム セル レンダラーを使用する必要があります。

ほぼすべてが機能するようになりましたが、欠けている部分が 1 つあります。セル レンダラーは、何をレンダリングするかを認識している必要があります。

レンダリングするデータはカスタム クラスです。そのクラスからフィールドを取得したい。

これが私がこれまでに持っているものです

public class TreeItemCellRenderer : CellRenderer
{
    public override void GetSize (Widget widget, ref Gdk.Rectangle cell_area, out int x_offset, out int y_offset, out int width, out int height)
    {
        base.GetSize (widget, ref cell_area, out x_offset, out y_offset, out width, out height);

        height = 16;
    }

    protected override void Render (Gdk.Drawable window,
        Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, CellRendererState flags)
    {
        base.Render (window, widget, background_area, cell_area, expose_area, flags);

        using (var layout = new Pango.Layout(widget.PangoContext)) {
            layout.Alignment = Pango.Alignment.Left;
            layout.SetText("Hello, World!");

            StateType state = flags.HasFlag(CellRendererState.Selected) ?
                widget.IsFocus ? StateType.Selected : StateType.Active : StateType.Normal;

            window.DrawLayout(widget.Style.TextGC(state), cell_area.X, cell_area.Y, layout);
        }
    }
}

ここで、"Hello, World!" の代わりにカスタム フィールドを描画したいと考えています。いくつかのグーグルが示唆したSetProperty/GetPropertyは私が必要とするものですが、:

var col = new TreeViewColumn("TreeItem", renderer);
col.AddAttribute(renderer, "tree-item", 0);

TreeItemCellRenderer には「tree-item」という名前のプロパティがないため、実行時にエラーがスローされます。また、仮想でSetPropertyないことに注意してください。

では、どうすればいいですか?

4

3 に答える 3

3

実際、唯一の問題は、カスタム セル レンダラーでレンダリングする値/データの定義が、レンダラー自体ではなく、外部のリスナー メソッドで行われることです。

TreeView とその列と CellRenderers を定義するウィジェット クラスでは、TreeCellDataFunc も定義できます。これは、セルがレンダリングされる前に呼び出されるリスナー関数のひどく隠された名前にすぎません。しかし、その名前にはすでに「データ」が含まれており、それがその関数内で行うべきことです。レンダリングするデータを提供します。

TreeItemCellRenderer cellRenderer = new TreeItemCellRenderer();
column.SetCellDataFunc(cellRenderer, new Gtk.TreeCellDataFunc(AwesomeDataFunction));

/**
* Supplies the TreeItemCellRenderer with data for the current cell.
* */
private void AwesomeDataFunction(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
{
    (cell as TreeItemCellRenderer).<some self-declared property> = <any fitting value>;
}

iter と model を使用して、必要なデータを取得したいと思うでしょう。CellRenderer の実際の Render() 関数は、その関数の後に呼び出されます。

全体として、TreeView/CellRenderer モデル全体が混乱していると思います。それは機能し、ほとんどのことを行うことができますが、目標を達成するために何をすべきかは完全に不明です. その 1 つの TreeView チュートリアルは問題ありませんが、実際には氷山の一角しか示していません。セルのレンダリングにウィジェットが使用されない理由はわかりません。はるかに簡単だったでしょう。

于 2012-03-25T15:12:48.630 に答える
0

実際の良い答えは見つかりませんでしたが、回避策は見つかりました。

私の目標は常に、その値を所有するクラスへの「ポインタ」を維持しながら情報を表示することでした。これが私がしたことです:

  1. 1つの列(「ラベル」)のみを宣言します
  2. 表示するラベルとクラスインスタンスの2つの列を持つ行を追加します。そうすれば、最初の行は表示されますが、2番目の行は非表示になります

これで、各行の2番目の列を取得すると、カスタムレンダラーを処理したり、ツリーにランダムデータを表示したりすることなく、必要な値が得られます。

私はこれが質問に答えないことを知っています、しかしそれは私の特定の問題を解決します。他の誰かがこのページにたどり着いた場合でも、この情報がまだ役立つことを願っています。しかし、より良い解決策を見つけた場合は、とにかくそれを投稿してください。

于 2011-11-27T01:14:19.870 に答える