Search code examples
c#buttontextboxruntime

How to delete a runtime-added button?


first, I'm a real beginner to c#, so please don't answer with expert-stuff, keep it simple, even if that is a longer variant than it would have to be, thanks!

I coded a little program, that is able to add so called "Notes" to the form during runtime.

Note is a class, that contains two buttons (remove, save) and a textbox. Another class, MyNotes, has a methode, that adds new Notes to the form up to max. 4.

So far it works perfectly.

Now the problem: I would like to delete the specific Note, for which the user presses the remove Button (so the two buttons and the textbox should be deleted from the form, but (if there are) other Notes should stay untouched.

I already programmed a remove method, but the problem is, that the "object sender" in "remove_Click" does deliver a remove Button, but there are no infos about the Note, he's a part of, or the other elements of his Note (save-button, textbox). I understand why, but I don't know, how to fix the problem.

How can I tell him of which Note he's a part?

EDIT: save_Click and button1_Click are not part of this, they have other functions, irrelevant for this.

EDIT2: That's a picture of the program. The 4 textboxes, save-buttons and x-buttons in the upper part were added by "ADD". The problem is to remove one "Note-set" by pressing "X" in one of the 4 cases. :-/

Click to see an image of my program

Form:

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

namespace TextboxTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            richTextBox1.BorderStyle = BorderStyle.None; 
        }

        private void load_Click(object sender, EventArgs e)
        {
            Note note = MyNotes.AddNote();
            if (note !=  null)
            {
                this.Controls.Add(note.GetBox());
                this.Controls.Add(note.GetRemoveButton());
                this.Controls.Add(note.GetSaveButton());

                note.GetRemoveButton().Click += new EventHandler(remove_Click);

            }
            richTextBox1.Text = MyNotes.SetNote();
        }

        private void remove_Click(object sender, EventArgs e)
        {
            Note note = sender as Note;

            Controls.Remove(note.GetBox());
            Controls.Remove(note.GetSaveButton());
            Controls.Remove(note.GetRemoveButton());
        }


        private void save_Click(object sender, EventArgs e)
        {
            String savePath = Properties.Settings.Default.datapath;
            System.IO.File.WriteAllText(savePath, richTextBox1.Text);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 settings = new Form2();
            settings.Show();
            MessageBox.Show("Selected Item Text: " + Properties.Settings.Default.textboxFont + "\n");
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            richTextBox1.Text = MyNotes.SetNote();
        }

    }
}

Class MyNotes:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TextboxTest
{
    class MyNotes
    {
        public static List<Note> noteList = new List<Note>();
        public static String path = Properties.Settings.Default.datapath;
        private static int y = 50;



        // Adds a new textbox, save- and remove-Button to the form (and the textBoxList) 
        // up to a maximum of 4 each.

        public static Note AddNote()
        {
            if (noteList.Count < 4)
            {
                Note note = new Note();
                note.GetBox().Location = new Point(100, y);
                note.GetRemoveButton().Location = new Point(15, y-2);
                note.GetSaveButton().Location = new Point(40, y - 2);
                y += 22;
                noteList.Add(note);
                return note;
            }
            else
            {
                MessageBox.Show("It's only possible to set a maximum of 4 notes. Please delete or rewrite another one.");
                return null;
            }
        }

        public static String SetNote()
        {
            return System.IO.File.ReadAllText(path);
        }


    }
}

Class Notes:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TextboxTest
{
    class Note
    {
        private TextBox box;
        private Button remove;
        private Button save;

        public Note()
        {
            boxSettings();
            removeSettings();
            saveSettings();
        }

        private void boxSettings()
        {
            box = new TextBox();
            box.Width = 250;
            box.BackColor = System.Drawing.Color.DarkGray;

        }

        private void removeSettings()
        {
            remove = new Button();
            remove.Text = "X";
            remove.TextAlign = ContentAlignment.MiddleCenter;
            remove.Width = 20;

        }

        private void saveSettings()
        {
            save = new Button();
            save.Text = "SAVE";
            save.TextAlign = ContentAlignment.MiddleCenter;
            save.Width = 50;

        }

        public TextBox GetBox()
        {
            return this.box;
        }

        public Button GetRemoveButton()
        {
            return this.remove;
        }

        public Button GetSaveButton()
        {
            return this.save;
        }


    }
}

Solution

  • You can make use of the Tag Property in this case. Think of the Tag property (found in each Control) as a placeholder that can hold an object.

    In your case, after a user clicks the "X" button you want to remove that note, the problem here is that in the click event you get the button itself and not the note. Here, you can store the Note object in your buttons so that you can then use them in the Click event.

    Code:

    // Class Note
    private void removeSettings()
    {
        remove = new Button();
        remove.Text = "X";
        remove.TextAlign = ContentAlignment.MiddleCenter;
        remove.Width = 20;
        remove.Tag = this; // Store the current Note in its remove button
    }
    
    // Class Form1
    private void remove_Click(object sender, EventArgs e)
    {
        Button btn = sender as Button;
        Note note = btn.Tag as Note;
    
        Controls.Remove(note.GetBox());
        Controls.Remove(note.GetSaveButton());
        Controls.Remove(note.GetRemoveButton());
    }
    

    Hope this is simple enough!