从GTK#NodeView获取选定的列

问题描述

我正在使用MonoDevelop在Raspberry Pi上编写一些C#代码。我有一个NodeView小部件,其中包含三列。我想检测在NodeView中单击的列。我尝试使用NodeSelection.Changed,但是,这并不告诉我该列。我还尝试过为NodeView编码一个ButtonPress事件,并深入到TreePath。我对此一无所知。

我已经注意到这个问题了好几次。但是,我没有看到一个直接的方法来获取NodeView中所选项目的行/列。

有人知道该怎么做吗?

解决方法

最后弄清楚了。这很痛苦,因为就像您所说的,关于此的零文档。

因此,要概述我所做的事情,这是我的窗口的外观: program

当我单击不同的列时,这是输出:

Clicked on column index 3 with title "hello 3"
Node selected: Prop1 29478338;Prop2 55998661;Prop3 1058200043;Prop4 1429485106
Clicked on column index 2 with title "hello 2"
Node selected: Prop1 1781730137;Prop2 618078535;Prop3 1253079243;Prop4 1149116957
Clicked on column index 1 with title "hello 1"
Node selected: Prop1 1577113328;Prop2 1907291485;Prop3 764000225;Prop4 1871218984
Clicked on column index 0 with title "hello 0"
Node selected: Prop1 1267506574;Prop2 692394441;Prop3 1291543143;Prop4 41456018
Clicked on column index 1 with title "hello 1"
Node selected: Prop1 1659363497;Prop2 873230641;Prop3 1799765877;Prop4 83248840
Clicked on column index 2 with title "hello 2"
Node selected: Prop1 1882743696;Prop2 419098689;Prop3 554049937;Prop4 671882960

和代码一样,它看起来并不“漂亮”(只是迅速地将其投入工作即可):

Random r = new Random();

[Gtk.TreeNode(ListOnly = true)]
public class MyTreeNode : Gtk.TreeNode
{
    public MyTreeNode(Random r)
    {
        AnotherProp1 = $"Prop1 {r.Next()}";
        AnotherProp2 = $"Prop2 {r.Next()}";
        AnotherProp3 = $"Prop3 {r.Next()}";
        AnotherProp4 = $"Prop4 {r.Next()}";
    }

    [Gtk.TreeNodeValue(Column = 0)]
    public string AnotherProp1 { get; private set; }

    [Gtk.TreeNodeValue(Column = 1)]
    public string AnotherProp2 { get; private set; }

    [Gtk.TreeNodeValue(Column = 2)]
    public string AnotherProp3 { get; private set; }

    [Gtk.TreeNodeValue(Column = 3)]
    public string AnotherProp4 { get; private set; }

    public override string ToString() =>
        $"{AnotherProp1};{AnotherProp2};{AnotherProp3};{AnotherProp4}";
}

private readonly NodeStore _store = new NodeStore(typeof(MyTreeNode));

public MainWindow() : base(Gtk.WindowType.Toplevel)
{
    Build();

    for (var i = 0; i < 6; ++i)
    {
        _store.AddNode(new MyTreeNode(r));
    }
    nodeview2.NodeStore = _store;

    nodeview2.AppendColumn("hello 0",new CellRendererText(),"text",0).Clickable = true;
    nodeview2.AppendColumn("hello 1",1).Clickable = true;
    nodeview2.AppendColumn("hello 2",2).Clickable = true;
    nodeview2.AppendColumn("hello 3",3).Clickable = true;

    // how to detect column header clicks:
    nodeview2.GetColumn(0).Clicked += (s,e) => Console.WriteLine("HERE 0");
    nodeview2.GetColumn(1).Clicked += (s,e) => Console.WriteLine("HERE 1");
    nodeview2.GetColumn(2).Clicked += (s,e) => Console.WriteLine("HERE 2");
    nodeview2.GetColumn(3).Clicked += (s,e) => Console.WriteLine("HERE 3");

    nodeview2.WidgetEvent += (s,e) =>
    {
        if ((e.Event is Gdk.EventButton ev) &&
           (ev.Type == Gdk.EventType.ButtonPress) &&
           (ev.Window == nodeview2.BinWindow))
        {
            if (nodeview2.GetPathAtPos((int)ev.X,(int)ev.Y,out var path,out var column))
            {
                // get the column index. There must be a better way?
                var columnIndex = nodeview2.Columns.Select(
                    (col,index) => new { col,index }).First(x => ReferenceEquals(x.col,column)).index;

                Console.WriteLine($"Clicked on column index {columnIndex} with title \"{column.Title}\"");

                var nodeValue = (MyTreeNode)_store.GetNode(path);
                Console.WriteLine($"Node selected: {nodeValue}");
            }
        }
    };

    nodeview2.ShowAll();
}

因此,这里的技巧是捕获EventButton的{​​{1}},然后获取坐标并将其传递给ButtonPress。返回列和路径信息。您可以使用它来导出所需的内容。我希望Gtk#有更好的文档记录/更广泛的使用。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...