Solved

C#  Drag and Drop PictureBox Problem

Posted on 2007-04-10
6
7,332 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
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

707 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now