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>(); // Категория к которой относится ссыль
}
Ответы (1 шт):
Я ведь правильно понял, что ты хочешь через цикл создавать 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);

