GTK#Nodeview Nodestore始终获取空引用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GTK#Nodeview Nodestore始终获取空引用相关的知识,希望对你有一定的参考价值。

我按照GTK #Mono教程页面中的代码创建了一个GTK#Nodeview + NodeStore!我的更改是添加一个按钮以向NodeView添加新条目并尝试使其可交互。我的问题是NodeView Selection Changed事件导致应用程序崩溃。

using System;
using Gtk;

public partial class MainWindow : Window
{
    Button button;
    NodeView nodeview;
    NodeStore nodestore;

    [TreeNode(ListOnly = true)]
    public class MyTreeNode : TreeNode
    {
        public MyTreeNode(string artist)
        {
            Artist = artist;
        }

        [TreeNodeValue(Column = 0)]
        public string Artist;
    }


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

        var vbox = new VBox();
        nodeview = new NodeView();
        // Create a column with title Artist and bind its renderer to model column 0
        nodeview.AppendColumn("Artist", new CellRendererText(), "text", 0);

        nodestore = new NodeStore(typeof(MyTreeNode));
        nodestore.AddNode(new MyTreeNode("temp"));
        nodeview.NodeStore = nodestore;

        nodeview.Selection.Changed += Selection_Changed;

        button = new Button("Add New!!");
        button.Clicked += Button_Clicked;

        vbox.PackStart(nodeview, true, true, 0);
        vbox.PackStart(button, false, true, 0);

        Add(vbox);
        ShowAll();
    }

    void Button_Clicked(object sender, EventArgs e)
    {
        nodestore.AddNode(new MyTreeNode("temp"));
    }

    void Selection_Changed(object sender, EventArgs e)
    {
        NodeSelection selection = (NodeSelection)sender;
        if (selection != null)
        {
            MyTreeNode node = (MyTreeNode)selection.SelectedNode;
            var a = node.Artist;
        }
    }

    protected void OnDeleteEvent(object sender, DeleteEventArgs a)
    {
        Application.Quit();
        a.RetVal = true;


    }
}

当我在NodeView中选择一个节点时,应用程序崩溃而没有任何通知。然后通过一些调试我意识到,当进入NodeSelection_Changed时,Nodeview中的NodeStore变量始终为null。即使它正在向它添加节点..(它们被渲染到nodeview)。

答案

这似乎是bug in GTK#一直是fixed但不是与Mono 5.8及更早版本一起发布的版本。

解决方法是使用反射在NodeView类中设置“store”字段。

typeof (NodeView).GetField ("store", BindingFlags.Instance | BindingFlags.NonPublic).SetValue (nodeview, nodestore);

如果您在NodeView上设置nodestore的行之后添加上面的行,那么这会将NodeView.NodeStore修复为null。

nodeview.NodeStore = nodestore;
typeof (NodeView).GetField ("store", BindingFlags.Instance | BindingFlags.NonPublic).SetValue (nodeview, nodestore);

另请注意,Selection_Changed事件中的代码失败,因为发件人是Gtk.TreeSelection而不是Gtk.NodeSelection。我将Selection_Changed方法更改为以下工作方式:

void Selection_Changed(object sender, EventArgs e)
{
    NodeSelection selection = nodeview.NodeSelection;
    if (selection != null)
    {
        MyTreeNode node = (MyTreeNode)selection.SelectedNode;
        var a = node.Artist;
    }
}

以上是关于GTK#Nodeview Nodestore始终获取空引用的主要内容,如果未能解决你的问题,请参考以下文章

Python Gtk 按钮

如何更改 GTK 容器小部件的大小?

在 GTK+ 中让窗口显示在全屏窗口上方

如何控制在树的展开行中可见哪些 GTK 小部件?

GtkScrolledWindow - 如何始终显示覆盖滚动条

显示尽可能大的所有小部件