Solved

C#  Drag and Drop PictureBox Problem

Posted on 2007-04-10
6
7,368 Views
Last Modified: 2008-09-12
Please help me....
I am stuggling with a drag and drop of picture boxes between panels (panel1 and panel2).   On the event where the directory chosen by the user changes, the method UpdateDisplay() is called (below).  What is happening is i am traversing thru the directory to display each picture box and upon dragging the picture from panel1 to panel2  an instance of the picturebox is created for each image in the directory.  

In simple talk...If i drag and drop an image from one panel to another, it gets copied 5 times to panel2 (because there are 5 images in the directory that panel one points to.

Please help as i need to work this one out urgently.  Many thanks in advance experts...







     private void UpdateDisplay()
        {
            // Clear the current display.
            panel1.Controls.Clear();

            // Row and Col will track the current position where pictures are
            // being inserted. They begin at the top-right corner.
            int row = border, col = border;

            // Iterate through the Images collection, and create PictureBox controls.
            foreach (NamedImage image in images)
            {
                PictureBox pic = new PictureBox();
                pic.Image = image.Image;
                pic.Tag = image.FileName;
                // pic.Size = new Size(dimension, dimension);
                pic.Location = new Point(col, row);
                pic.BorderStyle = BorderStyle.FixedSingle;

                // StrechImage mode gives us the "thumbnail" ability.
                pic.SizeMode = PictureBoxSizeMode.Zoom;

                // Display the picture.
                panel1.Controls.Add(pic);

                panel2.AllowDrop = true;
                this.AllowDrop = true;
                pic.MouseDown += new MouseEventHandler(FBox1_MouseDown);



                // Move to the next column.
                col += dimension + spacing;

                // Handle the event.
                pic.Click += new EventHandler(this.pic_Click);

                // Move to next line if no more pictures will fit.
                if ((col + dimension + spacing + border) > this.Width)
                {
                    col = border;
                    row += dimension + spacing;
                }
            }

            panel2.DragDrop += new DragEventHandler(groupBox2_DragDrop);
            panel2.DragEnter += new DragEventHandler(groupBox2_DragEnter);
            //    this.DragEnter += new DragEventHandler(groupBox2_DragEnter);

        }




        void FBox1_MouseDown(object sender, MouseEventArgs e)
        {
            DoDragDrop(((PictureBox)sender).Image, DragDropEffects.Copy);
        }

        void groupBox2_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }


        void groupBox2_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetData(typeof(Bitmap)) != null)
            {
                Bitmap FMap =
                      (Bitmap)e.Data.GetData(typeof(Bitmap));
                PictureBox FBox1 = new PictureBox
                      ();
                FBox1.Image = FMap;
                FBox1.SizeMode = PictureBoxSizeMode.Zoom;
                FBox1.Dock = DockStyle.Top;
                panel2.Controls.Add(FBox1);
            }
        }
0
Comment
Question by:cdempster
  • 3
  • 3
6 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 18891230
I don't understand what you are asking?  Do you not want it to get copied 5 times?

Bob
0
 

Author Comment

by:cdempster
ID: 18893229
That is correct, I don't want to get it copied 5 times.  I just want to drag the thumbnail from one panel to another and have it appear once in the second panel.

0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 18893549
So, is it happening in this for loop?

   foreach (NamedImage image in images)

I see where you are adding controls, but not where you clear them:

   panel1.Controls.Add(pic);

Bob
0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 

Author Comment

by:cdempster
ID: 18893917
I assume it must have something to do with the loop.  When i put in debug breakpoints, the mousedown event gets triggered only once but the dragdrop event gets triggered 5 times.  I'm not sure why i shoud be using the clear method.



Entire form code listing follows;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;

namespace thumbform
{
    public partial class Form2 : Form
    {

        // The Panels used for Drag and Drop
        private static string strImageFileName = "";
        private System.Windows.Forms.Panel panel1;
        private System.Windows.Forms.Panel panel2;
        private System.Windows.Forms.FolderBrowserDialog outputDirDialog = null;

        // The directory that will be scanned for image.
        private string directory = "";
        private string destDirectory = @"c:\tempfiles";
        private string strFileName = "";

        // Each picture box will be a square of dimension X dimension pixels.
        private int dimension;

        // The space between the images and the top, left, and right sides.
        private int border = 5;

        // The space between each image.
        private int spacing;

        // The images that were found in the selected directory.
        private ArrayList images = new ArrayList();
       
        // The selected images that were selected fromt the selected directory.
        private ArrayList selectedImages = new ArrayList();

        public string Directory
        {
            get
            {
                return directory;
            }
            set
            {
                directory = value;
                GetImages();
                UpdateDisplay();
            }
        }

        public int Dimension
        {
            get
            {
                return dimension;
            }
            set
            {
                dimension = value;
                UpdateDisplay();
            }
        }

        private int Spacing
        {
            get
            {
                return spacing;
            }
            set
            {
                spacing = value;
                UpdateDisplay();
            }
        }



        private void GetImages()
        {
            images.Clear();
            if (this.Directory != "" && this.directory != null)
            {
                DirectoryInfo dir = new DirectoryInfo(directory);
                foreach (FileInfo file in dir.GetFiles("*.jpg"))
                {
                    images.Add(new NamedImage(Bitmap.FromFile(file.FullName), file.Name));
                }
            }
        }

        private void UpdateDisplay()
        {
            // Clear the current display.
            panel1.Controls.Clear();

            // Row and Col will track the current position where pictures are
            // being inserted. They begin at the top-right corner.
            int row = border, col = border;

            // Initialise pic outside of foreach loop

            PictureBox pic;

            // Iterate through the Images collection, and create PictureBox controls.
            foreach (NamedImage image in images)
            {

                pic = new PictureBox();
                pic.Image = image.Image;
                pic.Tag = image.FileName;
                strImageFileName = image.FileName;

                pic.Size = new Size(dimension, dimension);
                pic.Location = new Point(col, row);
                pic.BorderStyle = BorderStyle.FixedSingle;

                // Zoom mode gives us the "thumbnail" ability within the border
                pic.SizeMode = PictureBoxSizeMode.Zoom; ;

                // Display the picture.

       
                panel1.Controls.Add(pic);
                 
             
                pic.MouseDown += new MouseEventHandler(FBox1_MouseDown);

                // Move to the next column.
                col += dimension + spacing;

             
                // Move to next line if no more pictures will fit.
                if ((col + dimension + spacing + border) > this.Width)
                {
                    col = border;
                    row += dimension + spacing;
                }
            }

            panel2.DragDrop += new DragEventHandler(groupBox2_DragDrop);
            panel2.DragEnter += new DragEventHandler(groupBox2_DragEnter);
            this.DragEnter += new DragEventHandler(groupBox2_DragEnter);

        }

     
        private class NamedImage
        {
            public Image Image;
            public string FileName;

            public NamedImage(Image image, string fileName)
            {
                this.Image = image;
                this.FileName = fileName;
            }
        }


        protected override void OnSizeChanged(System.EventArgs e)
        {
            UpdateDisplay();
            base.OnSizeChanged(e);
        }

        public Form2()
        {

            this.panel1 = new System.Windows.Forms.Panel();
            this.panel2 = new System.Windows.Forms.Panel();
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();
        }

        void FBox1_MouseDown(object sender, MouseEventArgs e)
        {
         
            if (e.Button == MouseButtons.Left)
            {
                DoDragDrop(((PictureBox)sender).Image, DragDropEffects.Copy);

                if (((PictureBox)sender).BackColor == this.BackColor)
                {

                    ((PictureBox)sender).BackColor = Color.White;
                    strFileName = "";
                }
                else
                {
                   
                 
                    ((PictureBox)sender).BackColor = this.BackColor;
                    strFileName = ((PictureBox)sender).Tag.ToString();
                    MessageBox.Show(Directory + @"\" + strFileName);
                 //   selectedImages
                }
            }
        }

        void groupBox2_DragEnter(object sender, DragEventArgs e)
        {
            int count = 0;
            if (count <= 1)
            {
                e.Effect = DragDropEffects.Copy;
                count++;
            }
        }


        void groupBox2_DragDrop(object sender, DragEventArgs e)
        {
               
                    if (e.Data.GetData(typeof(Bitmap)) != null)
                    {
                        Bitmap FMap = (Bitmap)e.Data.GetData(typeof(Bitmap));
                        PictureBox FBox1 = new PictureBox();
                        FBox1.Image = FMap;
                        FBox1.SizeMode = PictureBoxSizeMode.Zoom;
                        FBox1.Dock = DockStyle.Top;
                        panel2.Controls.Add(FBox1);
                    }
           
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>


        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
     

        private void Form1_Load(object sender, EventArgs e)
        {

            panel2.AllowDrop = true;
            this.AllowDrop = true;
            this.Spacing = 10;
            this.Dimension = 100; // Size of thumbnails
            this.Directory = @"C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures";
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        }

        private void btmSelectDirectory_Click(object sender, EventArgs e)
        {
             
            if (outputDirDialog == null)
            {
                outputDirDialog = new System.Windows.Forms.FolderBrowserDialog();
                outputDirDialog.Description = "Select Destination";
                outputDirDialog.ShowNewFolderButton = true;
            }

            outputDirDialog.ShowDialog();

            if (outputDirDialog.SelectedPath.Length == 0)
            {
                //  No destination selected
                statusLabel.Text = "No destination selected";
                return;
            }
            else
            {
                //  Directory Found
                statusLabel.Text = "";
            }

            SourceDirTextBox.Text = outputDirDialog.SelectedPath;
            this.Directory = outputDirDialog.SelectedPath;
        }

        private void btnTempDisplay_Click(object sender, EventArgs e)
        {


         // MessageBox.Show(selectedImages);

           
            foreach (NamedImage image in selectedImages)
            {

                PictureBox pic = new PictureBox();
                pic.Image = image.Image;
                pic.Tag = image.FileName;
               // testDisplay += testDisplay;
            }
       //     MessageBox.Show(testDisplay);
        }
       



    }


        #endregion
}
0
 

Author Comment

by:cdempster
ID: 18893921
Oh by the way, thanks for your help so far...
0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 500 total points
ID: 18897194
Ok, here's a different approach:

   How many times is UpdateDisplay called?  Every time it is called, you are adding an event handler to the panel:

            panel2.DragDrop += new DragEventHandler(groupBox2_DragDrop);

   But, you aren't removing any of the handlers.  With C#, you can have multiple event handlers for a single event.  With that syntax, you are adding a new handler every time 'UpdateDisplay' is called.  I would move this code into the form's constructor, or define it with the form's designer.

Bob
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question