我有一个TreeView,其Model是一个TreeModelSort,其中包含ListStore。我希望这个TreeView能够监听DragDataReceived。但是,当我将数据拖到它时,我收到此警告:
(TestDragDrop:4706):Gtk-WARNING **: 您必须覆盖默认值 GtkTreeView上的'drag_drop'处理程序 使用不支持的模型时 GtkTreeDragDest接口和 启用拖放功能。最简单的 这样做的方法是连接到 'drag_drop'并致电 g_signal_stop_emission_by_name()in 你的信号处理程序,以防止 运行默认处理程序。看着 默认的源代码 得到一个gtktreeview.c中的处理程序 想法你的处理程序应该做什么。 (gtktreeview.c在GTK源代码中 代码。)如果您正在使用GTK C语言以外的语言可能有 更自然的方式来覆盖默认 处理程序,例如通过推导。
我在Gtk#中有点迷失方向。消息说“如果你使用的是非C语言的GTK,可能有一种更自然的方式来覆盖默认处理程序,例如通过推导。”有人能指出一个这样的例子吗?究竟我最重要的是什么?没有DragDrop方法,并且重写OnDragDataReceived似乎不起作用。或者,我可以手动对ListStore进行排序,但这似乎是一个非常糟糕的主意(特别是因为似乎没有任何简单的方法来交换元素)。
以下是一个示例TreeView供参考:
using System;
using System.Linq;
using System.Text;
using Gtk;
namespace TestDragDrop
{
public class DestTreeView : TreeView
{
public DestTreeView ()
{
ListStore store = new ListStore (typeof (string));
TreeModelSort sort = new TreeModelSort (store) { DefaultSortFunc = BarSortFunc };
Model = sort;
TreeViewColumn column = new TreeViewColumn { Title = "Bar" };
CellRendererText cell = new CellRendererText ();
column.PackStart (cell, true);
column.SetCellDataFunc (cell, RenderBar);
AppendColumn (column);
EnableModelDragDest (Constants.Targets, Gdk.DragAction.Link);
DragDataReceived += HandleDragDataReceived;
store.AppendValues ("bar1");
store.AppendValues ("bar2");
}
string GetValueAtPos (int x, int y)
{
TreePath path;
TreeViewDropPosition pos;
if (!GetDestRowAtPos (x, y, out path, out pos))
return "";
TreeIter iter;
if (!Model.GetIter (out iter, path))
return "";
return (string) Model.GetValue (iter, 0);
}
void HandleDragDataReceived (object o, DragDataReceivedArgs args)
{
string text = System.Text.Encoding.UTF8.GetString (args.SelectionData.Data);
string val = GetValueAtPos (args.X, args.Y);
Console.WriteLine ("Data: '{0}'\nRow: '{1}'", text, val);
}
void RenderBar (TreeViewColumn column, CellRenderer renderer, TreeModel model, TreeIter iter)
{
((CellRendererText) renderer).Text = (string) model.GetValue (iter, 0);
}
int BarSortFunc (TreeModel model, TreeIter iter1, TreeIter iter2)
{
string bar1 = (string) model.GetValue (iter1, 0);
string bar2 = (string) model.GetValue (iter2, 0);
return bar1.CompareTo (bar2);
}
}
}
答案 0 :(得分:2)
Gtk#中drag_drop的默认处理程序是Widget.OnDragDrop。因此,您需要继承TreeView并覆盖该虚方法以抢占TreeView的内置TreeDragDest机制。
OnDragDrop的签名是:
protected virtual bool OnDragDrop(Gdk.DragContext context,int x,int y,uint time _)