-2

I have to pass data using the collection for two objects ( email, mobile). If I click the button subscriber or unsubscribe, the values that I enter should be stored and showed to another form if I click publish button. However, I require to use 'delegate' for this task.

This is the form that I handle value I entered

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

namespace Q1
{
    public partial class Form2 : Form
    {

        // declare delegate
        public delegate void PublishMessageDel(ArrayList publist);

        public PublishMessageDel publist = null;

        public void PublishMessage(ArrayList subscribers)
        {
            publist.Invoke(subscribers);
        }

        public Form2()
        {
            InitializeComponent();
            
        }

        private void btnBackToMain_Click(object sender, EventArgs e)
        {
            // back to first form when the buttom is clicked
            this.Hide();
            Form1 mainWindow = new Form1();
            mainWindow.ShowDialog();
            this.Close();
        }

        private void txtEmailTo_Validating(object sender, CancelEventArgs e)
        {
            if (ckbEmailTo.Checked)
            {
                IsEmailFormMatch();
            }
            else if (!ckbEmailTo.Checked)
            {
                btnSubscribe.Enabled = false;
                btnUnsubscribe.Enabled = false;

            }

        }

        private void txtTextTo_Validating(object sender, CancelEventArgs e)
        {
            if (ckbTextTo.Checked)
            {
                IsMobileFormMatch();
            }
            else if (!ckbTextTo.Checked)
            {
                btnSubscribe.Enabled = false;
                btnUnsubscribe.Enabled = false;

            }

        }


        // check valid email and button visibility
        public void IsEmailFormMatch()
        {
            string emailForm = (@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");

            if (!Regex.IsMatch(txtEmailTo.Text, emailForm))
            {
                MessageBox.Show("Invalid Email");
                btnSubscribe.Enabled = false;
                btnUnsubscribe.Enabled = false;
            }
            else
            {
                btnSubscribe.Enabled = true;
                btnUnsubscribe.Enabled = true;
            }
        }

        // check valid mobile and button visibility
        public void IsMobileFormMatch()
        {
            string mobileForm = (@"\d{3}-\d{3}-\d{4}");

            if (!Regex.IsMatch(txtTextTo.Text, mobileForm))
            {
                MessageBox.Show("Invalid Phone Number");
                btnSubscribe.Enabled = false;
                btnUnsubscribe.Enabled = false;
            }
            else
            {
                btnSubscribe.Enabled = true;
                btnUnsubscribe.Enabled = true;
            }
        }

        private void btnSubscribe_Click(object sender, EventArgs e)
        {
            ArrayList subscribers = new ArrayList();

            if (ckbEmailTo.Checked)
            {
                subscribers.Add(txtEmailTo.Text);
            }
            else if (ckbTextTo.Checked)
            {
                subscribers.Add(txtTextTo.Text);                
            }

            foreach (ArrayList list in subscribers)
            {
                PublishMessage(list);
            }
        }

        private void btnUnsubscribe_Click(object sender, EventArgs e)
        {
            ArrayList subscribers = new ArrayList();

            if (ckbEmailTo.Checked)
            {
                subscribers.Remove(txtEmailTo.Text);

            }
            else if (ckbTextTo.Checked)
            {
                subscribers.Remove(txtTextTo.Text);
            }

        }

    }
}

I think this part has a problem.

private void btnSubscribe_Click(object sender, EventArgs e)
        {
            ArrayList subscribers = new ArrayList();

            if (ckbEmailTo.Checked)
            {
                subscribers.Add(txtEmailTo.Text);
            }
            else if (ckbTextTo.Checked)
            {
                subscribers.Add(txtTextTo.Text);                
            }

            foreach (ArrayList list in subscribers)
            {
                PublishMessage(list);
            }
        }

        private void btnUnsubscribe_Click(object sender, EventArgs e)
        {
            ArrayList subscribers = new ArrayList();

            if (ckbEmailTo.Checked)
            {
                subscribers.Remove(txtEmailTo.Text);

            }
            else if (ckbTextTo.Checked)
            {
                subscribers.Remove(txtTextTo.Text);
            }

        }

This is the form if I click publish button, the textbox should have to show me the values that subscribed in the previous form.

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

namespace Q1
{
    public partial class Form3 : Form
    {
        Form2 fm2;
        public Form3()
        {
            InitializeComponent();
            
        }

        private void btnBackToMain3_Click(object sender, EventArgs e)
        {
            this.Hide();
            Form1 mainWindow = new Form1();
            mainWindow.ShowDialog();
            this.Close();
        }

        // change button visibility when the textbox is empty or not
        public void btnPublish_Click(object sender, EventArgs e)
        {
            Form2 fm2 = new Form2();

            var value = fm2.publist += Subscribe;
            txtSubscribers.Text += value;
            //fm2.PublishMessage();

        }

        public void Subscribe(ArrayList list)
        {
            ArrayList subscribers = list;
            txtSubscribers.Text += subscribers.ToString();
        }

        
    }
}

I think I used delegate not properly and stuck to link with it..

moony
  • 1
  • 5
  • I don't see any _question_ in your question. Please fix the post so that it includes a proper [mcve], a clear description of what the code does, how that's different from what you want, and what _specifically_ you need help with. – Peter Duniho Feb 11 '21 at 22:34

1 Answers1

0

This is using delegates microsoft guide.
"A delegate is a type that safely encapsulates a method, similar to a function pointer in C and C++. Unlike C function pointers, delegates are object-oriented, type safe, and secure. The type of a delegate is defined by the name of the delegate."

So, before invoking arrSubscribers.Invoke(list); you should make a method in Form3 which takes the signature of your delegate(you receive as a parameter your ArrayList arrSubscribers) and add the reference to fm2.arrSubscribers.

public void YourMethod(ArrayList arrSubscribers)
{
// Your code with subscribers here
}

fm2.arrSubscribers = YourMethod; or fm2.arrSubscribers += YourMethod;
Example:

    private ArrayList subscribers;
    public Form2(Form1 form)

    {
        InitializeComponent();
        form.arrSubscribers = MyMethod;
    }

    public void MyMethod(ArrayList list)
    {
        subscribers = list;
    }

    private void Click(object sender, EventArgs e)
    {
        var query = from string item in subscribers
                    select item;
        label1.Text = string.Join(", ", query);
    }
Serhii
  • 723
  • 1
  • 4
  • 12
  • After defining the method to invoke the delegate in Form3, I have to call the method in `btnPublish` button. But I how can call the ArrayList from From 2? `private void btnPublish_Click(object sender, EventArgs e) { Subscribe(); } public void Subscribe(ArrayList arrSubscribers) { fm2.arrSubscribers += Subscribe; } ` – moony Feb 11 '21 at 21:03
  • I have just added example to my answer. Also take into account that you should check if your delegate is not null before calling `arrSubscribers.Invoke(list);` – Serhii Feb 11 '21 at 21:37
  • I edit `delegate`, `btnSubscribe` parts, but not sure how can I link them to Form3 .. I edit last part of it. Could you check it? – moony Feb 12 '21 at 17:52
  • Could you describe your task in details? For which reason you must use delegate? Maybe you should use some service to store your subscribers and pass it to both forms? – Serhii Feb 13 '21 at 13:35
  • [Quick example] (https://gitlab.com/SerhiiMahera/delegate-win-forms) – Serhii Feb 13 '21 at 14:00
  • I have to use a delegate to store them.. Tasks: When Subscribe button is clicked, an object of SendViaEmail or/and an object of SendViaMobile is/are instantiated, and should be added to the corresponding collection(s) if the email or/and mobile has/have not been subscribed before; finish the subscription – moony Feb 13 '21 at 23:44