События в C#
class MainForm : Form
{
StreamReader sr;
FileInfo[] files;
DirectoryInfo dir;
myLabel[] lFiles;
int k;
public class myLabel : LinkLabel
{
public int num;
}
...
public MainForm()
{
...
dir = new DirectoryInfo(".");
files = dir.GetFiles("*.txt");
lFiles = new myLabel[files.Length];
k=0;
foreach (FileInfo fI in files)
{
lFiles[k] = new myLabel();
lFiles[k].num = k;
lFiles[k].Text = Convert.ToString(k+1) + ". " + fI.Name;
lFiles[k].Location = new Point(50, 30 * k + 50);
lFiles[k].AutoSize = true;
lFiles[k].Click += new EventHandler(lFiles_Click);
Controls.Add(lFiles[k]);
k++;
}
...
void lFiles_Click(object o, EventArgs a)
{
sr = files[???].OpenText();
str = sr.ReadLine();
...
}
...
}
Мне нужно в обработчике события обратиться к объекту, который вызвал событие, чтоб потом прочесть файл, на который указывает соответствующий Label.
sr = files[???].OpenText(); вместо вопросиков нужно подставить номер файла. Пытался обратиться к object o, но не выходит, он не указывает на объект-родитель.
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication2 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
BuildLabels(@"C:\25.04.2008"); // сканируем каталог (у меня там много *.txt файлов)
}
// список меток
private List<MyLabel> labels = new List<MyLabel>();
private void BuildLabels(string path) {
// очищаем существующие метки - тогда
// метод BuildLablels можно использовать многократно
foreach (MyLabel label in labels) {
Controls.Remove(label);
label.Dispose();
}
labels.Clear();
// для каждого файла создаем новую метку
// и добавляем ее в коллекцию контролов и
// список меток
int index = 0;
foreach (FileInfo file in new DirectoryInfo(path).GetFiles("*.txt")) {
MyLabel label = new MyLabel(index, file);
label.Location = new Point(50, 30 * index + 50);
label.AutoSize = true;
label.Click += new EventHandler(MyLabel_Click);
labels.Add(label);
Controls.Add(label);
++index;
}
}
private void MyLabel_Click(object sender, EventArgs e) {
MyLabel label = sender as MyLabel;
if (label != null) {
using (StreamReader reader = label.FileInfo.OpenText()) {
// делаем что-то с содержимым файла
}
}
}
}
public class MyLabel : LinkLabel {
public MyLabel(int index, FileInfo file_info) {
this.file_info = file_info;
this.Text = string.Format("{0}.{1}", index, file_info.Name);
}
private FileInfo file_info;
public FileInfo FileInfo {
get {
return file_info;
}
}
}
}
{
Controls.Remove(label);
label.Dispose();
}
А точно прокатит? По-моему, этот вызов здесь лишний...
Мамой клянусь. Я код тестировал лично.
Не нужно бояться вызывать Dispose() лишний раз - там стоит защита от поломки, тем более этот вызов лучше аннотирует код - хорошо видно что лейбла больше не будет использоваться.
З.Ы. Если ты про Controls.Remove, то он ни в коем случае не вызывает Dispose.
З.Ы.Ы. Ну впринципе да Controls.Remove можно посчитать лишним, просто если мы вызваем гдето Controls.Add, то и ремувуть тоже наверно стоит...
Не нужно бояться вызывать Dispose() лишний раз - там стоит защита от поломки, тем более этот вызов лучше аннотирует код - хорошо видно что лейбла больше не будет использоваться.
З.Ы. Если ты про Controls.Remove, то он ни в коем случае не вызывает Dispose.
З.Ы.Ы. Ну впринципе да Controls.Remove можно посчитать лишним, просто если мы вызваем гдето Controls.Add, то и ремувуть тоже наверно стоит...
Dispose() нужен безусловно, я про другое:
for (int i = 0; i < 10; i++)
{
list.Add(i);
}
foreach (int n in list)
{
if (n == 0)
list.Remove(n); // Должно возникнуть исключение
// при переходе в начало цикла
}
{
if (n == 0)
list.Remove(n); // Должно возникнуть исключение
// при переходе в начало цикла
}
Это понятно, известное свойство списка: нельзя изменять перечисляемую коллекцию. Но где этот код в приведенных примерах, хоть тресни - не вижу.
А FlowLayoutPanel эт дело. Топикстартер, слышишь?