C# 当模型为TreeModelSort时,如何在TreeView中侦听接收到的DragDarView?

C# 当模型为TreeModelSort时,如何在TreeView中侦听接收到的DragDarView?,c#,mono,gtk,gtk#,C#,Mono,Gtk,Gtk#,我有一个TreeView,它的模型是一个TreeModelSort,它的子对象是一个ListStore。我想让这张树景听德拉格达的音乐。但是,当我将数据拖动到其中时,会收到以下警告: (TestDragDrop:4706):Gtk警告**: 您必须覆盖默认值 GtkTreeView上的“拖放”处理程序 当使用不支持的模型时 GTKTreeDragTest接口和 启用拖放。最简单的 这样做的方法是连接到 “拖放”并调用 g_信号_停止_发射_按_name()输入 您的信号处理程序可以防止 默认处理

我有一个TreeView,它的模型是一个TreeModelSort,它的子对象是一个ListStore。我想让这张树景听德拉格达的音乐。但是,当我将数据拖动到其中时,会收到以下警告:

(TestDragDrop:4706):Gtk警告**: 您必须覆盖默认值 GtkTreeView上的“拖放”处理程序 当使用不支持的模型时 GTKTreeDragTest接口和 启用拖放。最简单的 这样做的方法是连接到 “拖放”并调用 g_信号_停止_发射_按_name()输入 您的信号处理程序可以防止 默认处理程序无法运行。看看 默认值的源代码 gtktreeview.c中的处理程序以获取 知道你的处理者应该做什么。 (gtktreeview.c位于GTK源代码中 代码。)如果您使用的是来自 除C语言外,可能还有 覆盖默认值的更自然的方法 处理程序,例如通过派生

我对如何在Gtk中做到这一点有些迷茫。消息说“如果您使用的GTK语言不是C语言,那么可能有一种更自然的方法来覆盖默认处理程序,例如通过派生。”有人能给我举个例子说明这是什么样子吗?我到底在推翻什么?没有DragDrop方法,覆盖OnDragDataReceived似乎不起作用。或者,我可以手动对ListStore进行排序,但这似乎是一个非常糟糕的主意(特别是因为似乎没有任何简单的方法来交换元素)

以下是一个示例树视图,以供参考:

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);
        }
    }
}

Gtk中拖放的默认处理程序是Widget.OnDragDrop。因此,您需要对TreeView进行子类化,并重写该虚拟方法,以抢占TreeView的内置TreeDragDest机制

OnDragDrop的此签名为:

受保护的虚拟bool-OnDragDrop(Gdk.DragContext上下文,int x,int y,uint-time)