Drag and drop files into program

时光毁灭记忆、已成空白 提交于 2020-06-26 14:36:11

问题


I'm using MonoDevelop tool.
I want to make program like below with GTK#;

1. User drags file to program's listView, tableView or whatever
2. Dragged file's list is printed on the program's window

But I'm almost new to GTK# and find the way how to drag and drop,
so I searched information about it and found this link like below.
http://developer.gnome.org/gtkmm-tutorial/3.0/sec-dnd-example.html.en

This is the code I tried to make program link suggested
(This link explains drag and drop in C++ and I had to make it the way like C#)

using Gtk; using System; using System.Collections; using System.Collections.Generic;

namespace DragAndDrop
{
    public class SharpApp: Window
    {
        Button btnDrag;
        Label lblDrop;
        HBox hbox;

        public SharpApp (): base("Title")
        {
            btnDrag = new Button("Drag Here");
            lblDrop = new Label("Drop Here");
            hbox = new HBox();

            SetDefaultSize(250,200);
            SetPosition (Gtk.WindowPosition.Center);
            DeleteEvent += (o, args) => Application.Quit ();

            // Targets
            List<TargetEntry> list
                = new List<TargetEntry> ();
            list.Add (new TargetEntry
                      ("STRING", TargetFlags.Widget, 0));
            list.Add (new TargetEntry
                      ("text/plain", TargetFlags.Widget, 0));

            // Drag site -----
            // Make btnDrag a DnD drag source:
            TargetEntry[] entries = list.ToArray();
            TargetEntry[] se = new TargetEntry[] {entries[0]};

            Drag.SourceSet (btnDrag, Gdk.ModifierType.ModifierMask,
                            se, Gdk.DragAction.Copy);

            // Connect signals
            btnDrag.DragDataGet += delegate
                (object o, DragDataGetArgs args) {
                Console.WriteLine ("Test");
                OnDragDataGet(args.Context,
                              args.SelectionData,
                              args.Info,
                              args.Time);
            };

            hbox.PackStart (btnDrag);

            // Drop site -----
            // Make lblDrop a DnD drop destination:
            TargetEntry[] de = new TargetEntry[] {entries[1]};

            Drag.DestSet (lblDrop, DestDefaults.Drop,
                          de, Gdk.DragAction.Copy);


            // Connect signals
            lblDrop.DragDataReceived += delegate
                (object o, DragDataReceivedArgs args) {
                Console.WriteLine ("Test");
                OnDragDataReceived(args.Context,
                                   args.X,
                                   args.Y,
                                   args.SelectionData,
                                   args.Info,
                                   args.Time);
            };

            // hbox
            hbox.PackStart (lblDrop);

            Add (hbox);

            ShowAll ();
        }

        // event handlers
        protected override void OnDragDataGet
            (Gdk.DragContext context, SelectionData sdata,
             uint info, uint time)
        {
            Console.WriteLine ("OnDragDataGet");

            string tmp = "I'm data!";
            byte[] b = new byte[tmp.Length];
            for (int i=0; i<tmp.Length; ++i)
                b[i] = (byte)tmp[i];

            sdata.Set(sdata.Target, 8, b, tmp.Length);
        }
        protected override void OnDragDataReceived
            (Gdk.DragContext context, int x, int y,
             SelectionData sdata, uint info, uint time)
        {
            Console.WriteLine ("OnDragDataReceived");

            int length = sdata.Length;
            if ((length>=0) && (sdata.Format==8))
            {
                Console.WriteLine ("Received \"{0}\" in label",
                                   sdata.Data.ToString());
            }

            Drag.Finish (context, false, false, time);
        }

        // main
        public static void Main (string[] args)
        {
            Application.Init ();
            new SharpApp();
            Application.Run ();
        }
    }
}

but the result tells me I might be wrong.. I thought the button will be moved
when I drag it, but the button didn't move at all. Is there anyone able to fix my problem?


回答1:


The following example prints into a label (called lblPath) the full path of the files dropped over it:

public partial class MainWindow: Gtk.Window
{
    /** Add a label to your project called lblPath **/
    public MainWindow () : base (Gtk.WindowType.Toplevel)
    {
        Build ();
        //media type we'll accept
        Gtk.TargetEntry [  ] target_table = 
            new TargetEntry [  ] {
            new TargetEntry ("text/uri-list", 0, 0),
            new TargetEntry ("application/x-monkey", 0, 1),
        };
        Gtk.Drag.DestSet (lblPath, DestDefaults.All, target_table, Gdk.DragAction.Copy);
        lblPath.DragDataReceived += new Gtk.DragDataReceivedHandler(OnLabelDragDataReceived);
    }

    void OnLabelDragDataReceived (object sender, Gtk.DragDataReceivedArgs args)
    {
        if (args.SelectionData.Length > 0) {
            byte[] data = args.SelectionData.Data;
            string files = System.Text.Encoding.UTF8.GetString (data);
            string file;
            string[] fileArray = files.Split ('\n');
            for (int i = 0; i < fileArray.Length - 1; i++) { //the last element is empty
                file = fileArray [i].Replace ("\r", "");
                if (file.StartsWith("file://"))
                    file = file.Substring(7); //for Windows should be 8
                lblPath.Text += file + "\n";
            }
        }
    }
}



回答2:


Self answer
I found tutorials about drag and drop here:
https://github.com/mono/gtk-sharp/blob/master/sample/TestDnd.cs
http://my.safaribooksonline.com/book/programming/mono/0596007922/gtksharp/monoadn-chp-4-sect-8

and I made a tutorial of drag and drop myself.
This is drop file tutorial.

using System;
using System.Collections;
using System.Collections.Generic;

// 1. Drop file tutorial
namespace DropFile
{
    public class App: Gtk.Window
    {
        Gtk.Label lbldrop;

        public App (): base ("Drop file")
        {
            this.SetDefaultSize (250, 200);
            this.SetPosition (Gtk.WindowPosition.Center);
            this.DeleteEvent += OnTerminated;

            this.lbldrop = new Gtk.Label ("Drop here!");
            Gtk.Drag.DestSet (this.lbldrop, 0, null, 0);
            this.lbldrop.DragDrop
                += new Gtk.DragDropHandler
                    (OnLabelDragDrop);
            this.lbldrop.DragDataReceived
                += new Gtk.DragDataReceivedHandler
                    (OnLabelDragDataReceived);

            Gtk.VBox vbox = new Gtk.VBox ();
            vbox.PackStart (this.lbldrop, true, true, 0);

            this.Add (vbox);
            this.ShowAll ();
        }

        void OnLabelDragDrop (object sender, Gtk.DragDropArgs args)
        {
            Gtk.Drag.GetData
                ((Gtk.Widget)sender, args.Context,
                 args.Context.Targets[0], args.Time);
        }
        void OnLabelDragDataReceived
            (object sender, Gtk.DragDataReceivedArgs args)
        {
            if (args.SelectionData.Length > 0
                && args.SelectionData.Format == 8) {

                byte[] data = args.SelectionData.Data;
                string encoded = System.Text.Encoding.UTF8.GetString (data);

                // I don't know what last object is,
                //  but I tested and noticed that it is not
                //  a path
                List<string> paths
                    = new List<string> (encoded.Split ('\r', '\n'));
                paths.RemoveAll (string.IsNullOrEmpty);
                paths.RemoveAt (paths.Count-1);

                for (int i=0; i<paths.Count; ++i)
                {
                    Console.WriteLine ("Path {0}: {1}", i, paths[i]);
                }
            }
        }

        bool Test (string str)
        {
            return true;
        }

        void OnTerminated (object sender, EventArgs args)
        {
            Gtk.Application.Quit ();
        }

        public static void Main (string[] args)
        {
            Gtk.Application.Init ();
            new App ();
            Gtk.Application.Run ();
        }
    }
}

And this is drag button tutorial.

using System;

// 2. Drag button tutorial
namespace DragButton
{
    public class App: Gtk.Window
    {
        enum StatusType
        {
            Checked,
            NotChecked
        }

        Gtk.Button btnDrag;
        Gtk.Label lblDrop;
        bool isChecked;
        Gtk.Statusbar sBar;

        public App (): base("Drag And Drop Complete")
        {
            this.SetDefaultSize (250, 200);
            this.SetPosition (Gtk.WindowPosition.Center);
            this.DeleteEvent += OnTerminated;

            this.isChecked = false;
            this.sBar = new Gtk.Statusbar ();
            sBar.Push ((uint)StatusType.NotChecked, "Not checked");

            this.btnDrag = new Gtk.Button ("Drag here");
            Gtk.Drag.SourceSet
                (this.btnDrag,
                 Gdk.ModifierType.Button1Mask
                 | Gdk.ModifierType.Button3Mask,
                 null,
                 Gdk.DragAction.Copy | Gdk.DragAction.Move);
            this.btnDrag.DragDataGet
                += new Gtk.DragDataGetHandler
                    (HandleSourceDragDataGet);
            this.btnDrag.DragDataDelete
                += new Gtk.DragDataDeleteHandler
                    (HandleSourceDragDataDelete);

            // set drop label as destination
            this.lblDrop = new Gtk.Label ("Drop here");
            Gtk.Drag.DestSet (this.lblDrop, 0, null, 0);
            this.lblDrop.DragMotion
                += new Gtk.DragMotionHandler
                    (HandleTargetDragMotion);
            this.lblDrop.DragDrop
                += new Gtk.DragDropHandler
                    (HandleTargetDragDrop);
            this.lblDrop.DragDataReceived
                += new Gtk.DragDataReceivedHandler
                    (this.HandleTargetDragDataReceived);
            this.lblDrop.DragDrop
                += new Gtk.DragDropHandler
                    (this.HandleStatBarDragDrop);

            Gtk.MenuBar bar = new Gtk.MenuBar ();
            Gtk.MenuItem item = new Gtk.MenuItem ("File");
            Gtk.Menu menu = new Gtk.Menu ();
            item.Submenu = menu;
            bar.Append (item);

            // accel key
            Gtk.AccelGroup ag = new Gtk.AccelGroup ();
            this.AddAccelGroup (ag);
            item = new Gtk.MenuItem ("Quit");
            item.Activated += OnTerminated;
            item.AddAccelerator
                ("activate", ag, new Gtk.AccelKey
                 (Gdk.Key.Q, Gdk.ModifierType.ControlMask, 
                 Gtk.AccelFlags.Visible));
            menu.Append (item);

            Gtk.VBox vbox = new Gtk.VBox();
            vbox.PackStart (bar, false, false, 0);

            Gtk.HBox hbox = new Gtk.HBox ();
            hbox.PackStart (this.btnDrag, true, true, 0);
            hbox.PackStart (this.lblDrop, true, true, 0);
            vbox.PackStart (hbox, true, true, 0);
            vbox.PackStart (sBar, false, false, 0);

            this.Add (vbox);
            this.ShowAll ();
        }

        void OnTerminated(object sender, EventArgs args)
        {
            Gtk.Application.Quit ();
        }
        void HandleSourceDragDataGet
            (object sender, Gtk.DragDataGetArgs args)
        {
            Console.WriteLine ("Source Drag Data Get");
            args.SelectionData.Text = "I'm data!";
        }
        void HandleSourceDragDataDelete
            (object sender, Gtk.DragDataDeleteArgs args)
        {
            Console.WriteLine ("Source Drag Data Delete");
            Console.WriteLine ("Delete the data!");
        }
        void HandleTargetDragMotion
            (object sender, Gtk.DragMotionArgs args)
        {
            Gdk.Drag.Status (args.Context,
                             args.Context.SuggestedAction,
                             args.Time);
            args.RetVal = true;
        }
        void HandleTargetDragDrop
            (object sender, Gtk.DragDropArgs args)
        {
            Console.WriteLine ("drop");
            if (args.Context.Targets.Length != 0) {
                Gtk.Drag.GetData
                    ((Gtk.Widget)sender, args.Context,
                     args.Context.Targets[0], args.Time);
                args.RetVal = true;
            }

            args.RetVal = false;
        }
        void HandleTargetDragDataReceived
            (object sender, Gtk.DragDataReceivedArgs args)
        {
            Console.WriteLine ("received");
            if (args.SelectionData.Length >= 0
                && args.SelectionData.Format == 8) 
            {
                Console.WriteLine ("Hi!");

                Gtk.Drag.Finish (args.Context, true, false, args.Time);
            }
            Gtk.Drag.Finish (args.Context, false, false, args.Time);
        }
        void HandleStatBarDragDrop
            (object sender, Gtk.DragDropArgs args)
        {
            isChecked = !isChecked;
            if (isChecked)
                sBar.Push ((uint)StatusType.Checked, "Checked");
            else
                sBar.Pop ((uint)StatusType.Checked);
        }

        public static void Main (string[] args)
        {
            Gtk.Application.Init ();
            new App ();
            Gtk.Application.Run ();
        }
    }
}


来源:https://stackoverflow.com/questions/14273471/drag-and-drop-files-into-program

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!