GTK# Nodeview Nodestore 总是获取空引用
GTK# Nodeview Nodestore always gets null reference
我已经按照 GTK# Mono 教程页面中的代码创建了一个 GTK# Nodeview + NodeStore!我的更改是添加一个按钮以将新条目添加到 NodeView 并尝试使其可交互。我的问题是 NodeView
选择更改事件导致应用程序崩溃。
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;
}
}
当我 select NodeView 中的一个节点时,应用程序在没有任何通知的情况下崩溃。然后通过一些调试,我意识到当输入 NodeSelection_Changed 时,Nodeview 中的 NodeStore 变量始终为空。即使它正在向它添加节点..(它们正在呈现给节点视图)。
这似乎是 bug in GTK# which has been fixed 但不是 Mono 5.8 及更早版本附带的版本。
解决方法是使用反射在 NodeView class 中设置 'store' 字段。
typeof (NodeView).GetField ("store", BindingFlags.Instance | BindingFlags.NonPublic).SetValue (nodeview, nodestore);
如果您将上面的行添加到在 NodeView 上设置节点存储的行之后,那么这将修复 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# Mono 教程页面中的代码创建了一个 GTK# Nodeview + NodeStore!我的更改是添加一个按钮以将新条目添加到 NodeView 并尝试使其可交互。我的问题是 NodeView 选择更改事件导致应用程序崩溃。
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;
}
}
当我 select NodeView 中的一个节点时,应用程序在没有任何通知的情况下崩溃。然后通过一些调试,我意识到当输入 NodeSelection_Changed 时,Nodeview 中的 NodeStore 变量始终为空。即使它正在向它添加节点..(它们正在呈现给节点视图)。
这似乎是 bug in GTK# which has been fixed 但不是 Mono 5.8 及更早版本附带的版本。
解决方法是使用反射在 NodeView class 中设置 'store' 字段。
typeof (NodeView).GetField ("store", BindingFlags.Instance | BindingFlags.NonPublic).SetValue (nodeview, nodestore);
如果您将上面的行添加到在 NodeView 上设置节点存储的行之后,那么这将修复 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;
}
}