Thank you very much for reading this. I've been programming for 15 years (VB, a lot of PHP, etc), but I've never considered myself a 'real' programmer. Mainly I'll build things that I need that are too specialized to be made by anyone else - simple programs and scripts to make life easier. I've managed to do what I needed without having to bother other people, but this time I'm a bit out of my depth. Before anyone jumps on me for not having a strong programming background or spending the weeks and months learning everything about C#, let me explain: My day job is in an unrelated field, I go to school at night, I'm married, and I have three great children. I've picked up and read through HeadFirst C#, but I'm having a hell of a time relating it to my own project. So I'm begging help from you guys ;)

I'm running .NET4.0 / VS 2010 on a Win7-64 machine.

I'm trying to create a program that will allow me to spawn boxes onto the screen to hold notes (Notebox) - similar to StickyNotes from Microsoft and 'bubbl.us' on the web. Each Notebox will have two textBoxes ('titleTextBox' and 'contentTextBox') and 3 control buttons (clickToMove, spawnNotebox, and delete). They're all arranged on backgroundImage (to make it easy to see). I've got the textBoxes hooked up to a SQL DB, and I've got the Notebox moving around the screen just fine. My problem is that I'm failing to understand how to create a new instance of the Notebox. While playing around with the Clone method, I managed to make an exact copy of the original Notebox appear, but it held the same information as the original and used the same row in the DB.

I'd like the user to be able to click on spawnNotebox and have another blank Notebox appear - with its own row in the DB and ready to recieve input. I realize I'm making some obvious rookie mistakes, but after strugging with it all last week I figured I'd better get help from some experts.

Ok, so the question is: How do I make a new and independent copy of my Notebox?

I've stripped my failed attempt at cloning out of the code. I have one form that I've maximized that the Notebox appears in. No other files.

From Form.cs:

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

namespace movableElementswDB
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public void ideasBindingNavigatorSaveItem_Click(object sender, EventArgs e)
        {
            this.Validate();
            this.ideasBindingSource.EndEdit();
            this.tableAdapterManager.UpdateAll(this.NoteboxDataSet);

        }

        public void ideasBindingNavigatorSaveItem_Click_1(object sender, EventArgs e)
        {
            this.Validate();
            this.ideasBindingSource.EndEdit();
            this.tableAdapterManager.UpdateAll(this.NoteboxDataSet);

        }

        public void Form1_Load(object sender, EventArgs e)
        {
            // TODO: This line of code loads data into the 'NoteboxDataSet.ideas' table. You can move, or remove it, as needed.
            this.ideasTableAdapter.Fill(this.NoteboxDataSet.ideas);

        }

        // Start of BOXEN
        public void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        int x = 1;
        int y = 1;

        public void pictureBox1_Enter(object sender, EventArgs e)
        {

        }

        // Storing begin point for1 (by the left  click)
        void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                x = e.X;
                y = e.Y;
            }
        }

        // Moving the BOXEN
        void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                clickToMove.Left += (e.X - x);
                clickToMove.Top += (e.Y - y);
                spawnNotebox.Left += (e.X - x);
                spawnNotebox.Top += (e.Y - y);
                delete.Left += (e.X - x);
                delete.Top += (e.Y - y);
                backgroundImage.Left += (e.X - x);
                backgroundImage.Top += (e.Y - y);
                titleTextBox.Left += (e.X - x);
                titleTextBox.Top += (e.Y - y);
                contentTextBox.Left += (e.X - x);
                contentTextBox.Top += (e.Y - y);
            }
        }



        public void titleTextBox_TextChanged(object sender, EventArgs e)
        {

        }

        public void contentTextBox_TextChanged(object sender, EventArgs e)
        {

        }

        public void siblingIcon_Click(object sender, EventArgs e)
        {

        }
        // End of BOXEN


    }
}

Thank you VERY much for taking the time to read this. I really do appreciate the help and I hope you don't feel like I've wasted your time with a silly question.

No question is a stupid question ;]

I think what you want to try is:

...

public void siblingIcon_Click(object sender, EventArgs e)
{
	Form1 sibling = new Form1();
	sibling.Show();
}

Let me know how that goes.

No question is a stupid question ;]

I think what you want to try is:

...

public void siblingIcon_Click(object sender, EventArgs e)
{
	Form1 sibling = new Form1();
	sibling.Show();
}

Let me know how that goes.

Kimpl,
Thanks so much for replying!

The snippet you posted makes a whole new form appear - not just the Notebox part of it. I think I can see where I started to make my mistake tho. I haven't created a class for the Notebox itself. If I had, I think I could just use your snippet to fire off another copy of it. I understand how to create a class, but I need to figure out exactly how to take what I already have and make THAT into a class. Any suggestions would be very welcome.

Thanks!

Oh I see what you're doing. You've got this Form1, and you have a pictureBox control inside the form that acts as the 'Notebox' right? Then inside the pictureBox control there are each of the controls for the Notebox.. such as title etc.

And what you want to do is create a new instance of this everytime you click spawn?

Oh I see what you're doing. You've got this Form1, and you have a pictureBox control inside the form that acts as the 'Notebox' right? Then inside the pictureBox control there are each of the controls for the Notebox.. such as title etc.

And what you want to do is create a new instance of this everytime you click spawn?

Exactly!

Ok well I think the easiest way to approach this is that rather than using a single pictureBox (because you cannot create another instance of this, you'd need to dynamically create a new pictureBox and add event listeners), you want to make a new Windows Form.

Create a new Windows Form, call it 'Notebox'.

In the Notebox forms properties, make the following changes:
Change the FormBorderStyle to FixedToolWindow.
Change the ShowInTaskBar to false.

Then size / color the form how you wish. Add the necessary textboxes to the form to replicate the Notebox you've been using as a picturebox.

Now, to call each new instance of the Notebox, all you need to do is:

Notebox noteboxSibling = new Notebox();
noteboxSibling.TopLevel = false; // Renders the new Notebox instance a non top level control, making it sit inside Form1
this.Controls.Add(noteboxSibling); // Adds new Notebox instance to form as a control
noteboxSibling.Show(); // Shows the new Notebox instance
noteBoxSibling.BringToFront(); // Focuses on the new Notebox instance

// Optional code to place it where you want to make things tidier
noteboxSibling.Location = new Point(8, 8);
Comments
Perfect helpful answer. Thanks!

That works beautifully. I just have one question:

I was originally trying to get it all to work within a single form because I'd like to be able to use more area than may be available at my current monitor's resolution (1680x1050). By using one form to hold it all, I'd be able to use scroll bars on that form to navigate an area larger than my monitor for the hundreds of notes I plan on having.

Is there a way to accomplish this with the multiple-form method you've shown me?

That's incredibly simple.

Add a panel to Form1 and call it scrollPanel.

Then change AutoScroll to true, and just change the above code around to this:

Notebox noteboxSibling = new Notebox();
noteboxSibling.TopLevel = false; // Renders the new Notebox instance a non top level control, making it sit inside Form1
this.Controls.scrollPanel.Add(noteboxSibling); // Adds new Notebox instance to the scrollPanel as a control
noteboxSibling.Show(); // Shows the new Notebox instance
noteBoxSibling.BringToFront(); // Focuses on the new Notebox instance

// Optional code to place it where you want to make things tidier
noteboxSibling.Location = new Point(8, 8);

Notice all you have to do is change it to add to the scrollPanel controls rather than Form1 controls.

Edited 6 Years Ago by Kimpl: n/a

Ok, first off: Thank you for all of your help! I now realize I was going in the complete wrong direction before. I feel like a bit of a fool.

When I try to implement the scrollPanel, I'm getting this error:

Error 1 'System.Windows.Forms.Control.ControlCollection' does not contain a definition for 'scrollPanel' and no extension method 'scrollPanel' accepting a first argument of type 'System.Windows.Forms.Control.ControlCollection' could be found (are you missing a using directive or an assembly reference?) C:\Users\Desktop\C Sharp\Kimpl\Kimpl\Notebox.cs 39 27 Kimpl

(I'm getting the same error in Form.cs and Notebox.cs) I'm not calling scrollPanel in the correct namespace, am I? I searched around for a solution, but all of the information I found pointed to using and IDE that was either too new or too old. I'm using Visual Studio 2010 with .NET 4.

My code for Form.cs:

namespace Kimpl
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void noteBoxSibling_Click(object sender, EventArgs e)
        {

            Notebox noteboxSibling = new Notebox();
            noteboxSibling.TopLevel = false; // Renders the new Notebox instance a non top level control, making it sit inside Form1
            this.Controls.scrollPanel.Add(noteboxSibling); // Adds new Notebox instance to the scrollPanel as a control
            noteboxSibling.Show(); // Shows the new Notebox instance
            noteBoxSibling.BringToFront(); // Focuses on the new Notebox instance

        }
    }
}

And my code for Notebox.cs:

namespace Kimpl  
{
    public partial class Notebox : Form
    {
        public Notebox()
        {
            InitializeComponent();
        }

        private void boxenBindingNavigatorSaveItem_Click(object sender, EventArgs e)
        {
            this.Validate();
            this.boxenBindingSource.EndEdit();
            this.tableAdapterManager.UpdateAll(this.noteboxDataSet);

        }

        private void Notebox_Load(object sender, EventArgs e)
        {
            // TODO: This line of code loads data into the 'noteboxDataSet.boxen' table. You can move, or remove it, as needed.
            this.boxenTableAdapter.Fill(this.noteboxDataSet.boxen);

        }

        private void noteBoxSibling_Click(object sender, EventArgs e)
        {

            Notebox noteboxSibling = new Notebox();
            noteboxSibling.TopLevel = false; // Renders the new Notebox instance a non top level control, making it sit inside Form1
            this.Controls.scrollPanel.Add(noteboxSibling); // Adds new Notebox instance to the scrollPanel as a control
            noteboxSibling.Show(); // Shows the new Notebox instance
            noteBoxSibling.BringToFront(); // Focuses on the new Notebox instance

        }
    }
}

Ah sorry I didn't explain myself properly.

What I ment was that you need to add a normal panel control to Form1 using the designer, and make the panel cover the entire form, as well as anchoring to the left, right, top and bottom.

1) Add panel to Form1
2) Rename panel to 'scrollPanel'
3) Change panel properties:
- Name: scrollPanel
- AutoScroll: true
- Dock: Fill

Then your code should work.

My apologies for the confusion.

Kimpl, you're the man! Thank you very much for all your help! I'm sure you've earned some serious karma points today :cool:


Using the panel wasn't necessary and was still giving me errors for some reason. I was able to set Form1 to have the autoscroll properties and it gave me the result I wanted. With all the help you've given me this morning, I really feel like I'm getting a grasp on C#. Several key things have become clear to me and I'm comprehending the methodology a lot better. Thank you again!

You're more than welcome dude :] If it was helpfull I think there's a thanks button somewhere :p Best of luck! Don't be afraid to ask more questions around here..

And C# is definitely a great language to build on, you can do countless things with it.

You should also mark the thread as solved..

Edited 6 Years Ago by Kimpl: n/a

This question has already been answered. Start a new discussion instead.