WindowsForm. Создание и вывод элементов и событий через цикл For

Всем привет. С#. Найти в интернете ответ на свой вопрос не смог. Проблема в следующем: к каждому выведенному LinkLabel мне нужно вывести своё событие по клику на него (открывать ссылочку).

public partial class Links : Form
    {
        private UsersLinks link = new UsersLinks(); // Экземпляр класса ссылочек.
        int id = 0;
        string name = "";
        const string path = "system"; //cистемная папочка нашей программы.
        string fileForLinks="";
        
        public Links(String Data, int ID)
        {
            name = Name; //поднимаю на 1 область видимости выше.
            id = ID;  //поднимаю на 1 область видимости выше.
            InitializeComponent();

            //имя файла в котором его личный экземпляр класса Links
            fileForLinks = @path + GetHash(id.ToString()) + ".data "; 

            LoadLinks();
        }



        private void LoadLinks() //загружаем ссылки из файла + дешифруем в привычный нам.
        {
                FileStream fs = new FileStream(fileForLinks, FileMode.Open);
                BinaryFormatter formatter = new BinaryFormatter();
                link = (UsersLinks)formatter.Deserialize(fs);
                fs.Close();
              
                int stepWidth = 0;
                int stepHeight = 0;
// Перебираем все имеющиеся ссылки.
//При наличии выводим их на экран
                for (int i = 0; i < link.ID.Count; i++)  
                {
                    //создаю объект и наделяю мной желаемыми свойствами
                    var linkLabel  = new LinkLabel(); 
                    linkLabel.Visible = true;
                    linkLabel.TextAlign = ContentAlignment.MiddleCenter;
                    linkLabel.BackColor = System.Drawing.SystemColors.Highlight;
                    linkLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
                    linkLabel.ForeColor = System.Drawing.Color.White;
                    linkLabel.Location = new System.Drawing.Point(stepWidth, stepHeight);
                    linkLabel.Name = @"linkLabel"+i.ToString();
                    linkLabel.Text = link.LinkName[i];
                    //linkLabel.AutoSize = true;
                    linkLabel.Size = new System.Drawing.Size(190,15);
                    
                    //выбираю в какой столбец в форме поместить эту ссылку.
                    this.Controls.Add(linkLabel);
                    if      (link.CategoryLink[i] == "0") { panel6.Controls.Add(linkLabel); }
                    else if (link.CategoryLink[i] == "1") { panel3.Controls.Add(linkLabel); }
                    else if (link.CategoryLink[i] == "2") { panel4.Controls.Add(linkLabel); }
                    else if (link.CategoryLink[i] == "3") { panel5.Controls.Add(linkLabel); }
                    else    {return;}
                    linkLabel.BringToFront();

// далее начинаются проблемы.
// в этом же цикле, я инициализирую событие при клике на созданную только что ссылку. 
// Создаю метод для этого события.
// но сколько бы я не пытался к linkLabel присобачить [i] - это невозможно. 
// как бы мне выйти из этой ситуации? 
// результат работы программы один и тот же при любых моих попытках: 
// или ошибка компиляции, или при клике на любой linkLabel из выведенных
// юзается событие последнего записанного! вывод один. Перезаписывается.
// не могу понять как бы сотворить linkLabel[i].LinkClicked+=.... 
// и void linkLabel[i]_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)

linkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(linkLabel_LinkClicked); //инициализирую событие указанное ниже

void linkLabel_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e) //объясняю это  событие
    {
       linkLabel.LinkVisited = true;
       System.Diagnostics.Process.Start(link.Link[i - 1]); 
    }
stepHeight += 20; //cледующая ссылка будет ниже на 20px.
} //КОНЕЦ ЦИКЛА FOR
        
        public string GetHash(string input) //метод ХЕШИРУЮЩИЙ методом MD5.(без соли)
        {
            var md5 = System.Security.Cryptography.MD5.Create();
            var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
            return Convert.ToBase64String(hash);
        }
    }

класс UsersLinks (от которого объект link) выглядит следующим образом:

class UsersLinks
    {
        public List<string> ID = new List<string>(); // уникальный идентификатор.     //Если не string - работать не будет. Ибо List. С другой стороны - так лучше.
        public List<string> Link = new List<string>(); // Сама ссылка (URL)
        public List<string> LinkName = new List<string>(); // Имя ссылки
        public List<string> CategoryLink = new List<string>(); // Категория к которой относится ссыль
    }

Скрин формы [Вот я понавтыкал i, и мне сразу красным подчёркивает2


Ответы (1 шт):

Автор решения: Frehzy

Я ведь правильно понял, что ты хочешь через цикл создавать LinkLabel, который, при клике на них, делают какое-то действие, так? А в чём тогда проблема создавать их программно и сразу привязывать клик. Например, ниже написал код привязки элемента к ивенту, в который мы передаём нужный параметр:

*someButton*.Click += (sender, e) => OpenLink(sender, e, *someLink*);

void OpenLink(object sender, EventArgs e, string *someLink*)
{
        //some code
}

Например, через foreach перебираем все элементы листа и в качестве параметра передаём то, что нужно открыть. Чтобы потом добавить все программно созданные контролы, используй Controls.Add

UPD:

    private void Form1_Load(object sender, EventArgs e)
    {
        List<string> list = new()
        { 
            "1",
            "2",
            "3",
            "4",
            "5",
            "6",
            "7",
            "8",
            "9"
        };
        LoadButton(list);
    }

    private void LoadButton(IEnumerable<string> list)
    {
        foreach (var item in list)
        {
            Button button = new();
            button.Text = item.ToString();
            button.Click += (sender, e) => Button_Click(sender, e, item);
            tableLayoutPanel1.Controls.Add(button);
        }
    }

    private void Button_Click(object sender, EventArgs e, string text) =>
        MessageBox.Show(text);
→ Ссылка