Forum

Пожалуйста or Регистрация для создания сообщений и тем.

Ошибка при чтении файла. Нужна помощь

Добрый день! В проекте создаю кнопки и им присваиваю имена из текстового файла. Также хочу что бы по нажатию на кнопку в MessageBox выводилось название файла указанное в файле после названия
Файл выглядит вот так:

string file = "Debug\Файл.txt";
//Название кнопки 1 
//название файла
//Название кнопки 2
//название файла
//Название кнопки 3
//название файла
//Название кнопки 4
//название файла
//Название кнопки 5
//название файла

Вот мой код:

Спойлер

int count = File.ReadAllLines(file).Length / 2; // Узнаю количество кнопок которое надо создать
Point p1 = new Point(50,100);
string [] str;
Button[] buttons = new Button[count];
using (StreamReader read = new StreamReader(file,Encoding.UTF8))
{
str = read.ReadToEnd().Split(new char[] { '\n'});
string[] pdf = new string[count]; // массив для названий кнопок
string[] name = new string[count]; // массив для названий файлов
for(int i =0; i<str.Length;i++) // заполняю массивы name и pdf
{
if (i % 2 == 0) name[i / 2] = str[i];
else pdf[i / 2] = str[i];
}
for (int i =0;i<count;i++)
{

buttons[i] = new Button();
buttons[i].Location = new Point(p1.X, p1.Y);
buttons[i].Width = 100;
buttons[i].Height = 30;
buttons[i].Text = name[i];
buttons[i].Click += Method;
void Method (object sender2, EventArgs e2) // сделал по совету Хачатура с ютуба
{
MessageBox.Show(name[i]); // здесь вылазит ошибка , что инедкс находится вне границ массива
}

this.Controls.Add(buttons[i]);
p1.Y += 60;
}

}


Вопрос: Из за чего вылазит ошибка? И как ее по возможности исправить
P.S: Код старался выложить так, что бы  у всех работал

Можно сократить код до такого:

Спойлер

string file_name = "file.ini";

            string[] file = File.ReadAllLines(file_name);
            int count = file.Length / 2;
            Point p1 = new Point(50, 100);
            Button[] buttons = new Button[count];
            for (int i = 0; i < count; i++)
            {
                string name = file[i*2];
                string f = file[i*2+1]; // название файла
                buttons[i] = new Button();
                buttons[i].Location = new Point(p1.X, p1.Y);
                buttons[i].Width = 300;
                buttons[i].Height = 30;
                buttons[i].Text = name;
                buttons[i].Click += Method;
                void Method(object sender2, EventArgs e2) 
                {
                    MessageBox.Show(f); 
                }

                this.Controls.Add(buttons[i]);
                p1.Y += 60;
            }


Демо-видео

Удаленный пользователь отреагировал на эту запись.
Удаленный пользователь

Привет 🖐
Чтобы не мучиться с координатами, проще кнопки бросать на FlowLayoutPanel.
Ну, и если очень хочется лямбдой сделать, но при этом не нарушать index, то можно воспользоваться таким лайфхаком: тупо узнать, кто есть sender (s).

Ниже полный и при этом предельно короткий вариант, но разобраться сможешь.

Спойлер

string file = @"C:\Путь к файлу\1.txt";
List<string> lines = File.ReadAllLines(file).ToList();
int count = lines.Count();
Button[] buttons = new Button[count];
FlowLayoutPanel flow = new FlowLayoutPanel { Size = new Size(205, 500) };
Controls.Add(flow);

for (int i = 0; i < count; i += 2)
{
    buttons[i] = new Button { Text = lines[i], Width = 200, Height = 30, Name = i.ToString() };
    buttons[i].Click += (s, a) => MessageBox.Show(lines[Convert.ToInt32(((Button)s).Name) + 1]);
    flow.Controls.Add(buttons[i]);
}


[simple_tooltip content='Имя кнопки 1
Описание 1
Имя кнопки 2
Описание 2
Имя кнопки 3
Описание 3
Имя кнопки 4
Описание 4
Имя кнопки 5
Описание 5']Содержимое 1.txt[/simple_tooltip]

Удаленный пользователь отреагировал на эту запись.
Удаленный пользователь
Цитата: Adler от 18.11.2020, 14:38

Можно сократить код до такого:

Спойлер

 
 
 
 
string file_name = "file.ini";
 
string[] file = File.ReadAllLines(file_name);
int count = file.Length / 2;
Point p1 = new Point(50, 100);
Button[] buttons = new Button[count];
for (int i = 0; i < count; i++)
{
string name = file[i*2];
string f = file[i*2+1]; // название файла
buttons[i] = new Button();
buttons[i].Location = new Point(p1.X, p1.Y);
buttons[i].Width = 300;
buttons[i].Height = 30;
buttons[i].Text = name;
buttons[i].Click += Method;
void Method(object sender2, EventArgs e2)
{
MessageBox.Show(f);
}
 
this.Controls.Add(buttons[i]);
p1.Y += 60;
}
string file_name = "file.ini"; string[] file = File.ReadAllLines(file_name); int count = file.Length / 2; Point p1 = new Point(50, 100); Button[] buttons = new Button[count]; for (int i = 0; i < count; i++) { string name = file[i*2]; string f = file[i*2+1]; // название файла buttons[i] = new Button(); buttons[i].Location = new Point(p1.X, p1.Y); buttons[i].Width = 300; buttons[i].Height = 30; buttons[i].Text = name; buttons[i].Click += Method; void Method(object sender2, EventArgs e2) { MessageBox.Show(f); } this.Controls.Add(buttons[i]); p1.Y += 60; }
 
string file_name = "file.ini";

            string[] file = File.ReadAllLines(file_name);
            int count = file.Length / 2;
            Point p1 = new Point(50, 100);
            Button[] buttons = new Button[count];
            for (int i = 0; i < count; i++)
            {
                string name = file[i*2];
                string f = file[i*2+1]; // название файла
                buttons[i] = new Button();
                buttons[i].Location = new Point(p1.X, p1.Y);
                buttons[i].Width = 300;
                buttons[i].Height = 30;
                buttons[i].Text = name;
                buttons[i].Click += Method;
                void Method(object sender2, EventArgs e2) 
                {
                    MessageBox.Show(f); 
                }

                this.Controls.Add(buttons[i]);
                p1.Y += 60;
            }


Демо-видео

Спасибо!! Все работает.

Цитата: XpucT от 18.11.2020, 14:39

Привет 🖐
Чтобы не мучиться с координатами, проще кнопки бросать на FlowLayoutPanel.
Ну, и если очень хочется лямбдой сделать, но при этом не нарушать index, то можно воспользоваться таким лайфхаком: тупо узнать, кто есть sender (s).

Ниже полный и при этом предельно короткий вариант, но разобраться сможешь.

Спойлер

 
 
 
 
string file = @"C:\Путь к файлу\1.txt";
List<string> lines = File.ReadAllLines(file).ToList();
int count = lines.Count();
Button[] buttons = new Button[count];
FlowLayoutPanel flow = new FlowLayoutPanel { Size = new Size(205, 500) };
Controls.Add(flow);
 
for (int i = 0; i < count; i += 2)
{
buttons[i] = new Button { Text = lines[i], Width = 200, Height = 30, Name = i.ToString() };
buttons[i].Click += (s, a) => MessageBox.Show(lines[Convert.ToInt32(((Button)s).Name) + 1]);
flow.Controls.Add(buttons[i]);
}
string file = @"C:\Путь к файлу\1.txt"; List<string> lines = File.ReadAllLines(file).ToList(); int count = lines.Count(); Button[] buttons = new Button[count]; FlowLayoutPanel flow = new FlowLayoutPanel { Size = new Size(205, 500) }; Controls.Add(flow); for (int i = 0; i < count; i += 2) { buttons[i] = new Button { Text = lines[i], Width = 200, Height = 30, Name = i.ToString() }; buttons[i].Click += (s, a) => MessageBox.Show(lines[Convert.ToInt32(((Button)s).Name) + 1]); flow.Controls.Add(buttons[i]); }
 
string file = @"C:\Путь к файлу\1.txt";
List<string> lines = File.ReadAllLines(file).ToList();
int count = lines.Count();
Button[] buttons = new Button[count];
FlowLayoutPanel flow = new FlowLayoutPanel { Size = new Size(205, 500) };
Controls.Add(flow);

for (int i = 0; i < count; i += 2)
{
    buttons[i] = new Button { Text = lines[i], Width = 200, Height = 30, Name = i.ToString() };
    buttons[i].Click += (s, a) => MessageBox.Show(lines[Convert.ToInt32(((Button)s).Name) + 1]);
    flow.Controls.Add(buttons[i]);
}


[simple_tooltip content='Имя кнопки 1
Описание 1
Имя кнопки 2
Описание 2
Имя кнопки 3
Описание 3
Имя кнопки 4
Описание 4
Имя кнопки 5
Описание 5']Содержимое 1.txt[/simple_tooltip]

Спасибо за ответ!! Но пожалуй пока воспользуюсь кодом Adler'a, т.к пока с FlowLayouPanel не работал, как разберусь заменю на твой, более короткий вариант.

Цитата: Adler от 18.11.2020, 14:38

Можно сократить код до такого:

Спойлер

 
 
 
 
string file_name = "file.ini";
 
string[] file = File.ReadAllLines(file_name);
int count = file.Length / 2;
Point p1 = new Point(50, 100);
Button[] buttons = new Button[count];
for (int i = 0; i < count; i++)
{
string name = file[i*2];
string f = file[i*2+1]; // название файла
buttons[i] = new Button();
buttons[i].Location = new Point(p1.X, p1.Y);
buttons[i].Width = 300;
buttons[i].Height = 30;
buttons[i].Text = name;
buttons[i].Click += Method;
void Method(object sender2, EventArgs e2)
{
MessageBox.Show(f);
}
 
this.Controls.Add(buttons[i]);
p1.Y += 60;
}
string file_name = "file.ini"; string[] file = File.ReadAllLines(file_name); int count = file.Length / 2; Point p1 = new Point(50, 100); Button[] buttons = new Button[count]; for (int i = 0; i < count; i++) { string name = file[i*2]; string f = file[i*2+1]; // название файла buttons[i] = new Button(); buttons[i].Location = new Point(p1.X, p1.Y); buttons[i].Width = 300; buttons[i].Height = 30; buttons[i].Text = name; buttons[i].Click += Method; void Method(object sender2, EventArgs e2) { MessageBox.Show(f); } this.Controls.Add(buttons[i]); p1.Y += 60; }
 
string file_name = "file.ini";

            string[] file = File.ReadAllLines(file_name);
            int count = file.Length / 2;
            Point p1 = new Point(50, 100);
            Button[] buttons = new Button[count];
            for (int i = 0; i < count; i++)
            {
                string name = file[i*2];
                string f = file[i*2+1]; // название файла
                buttons[i] = new Button();
                buttons[i].Location = new Point(p1.X, p1.Y);
                buttons[i].Width = 300;
                buttons[i].Height = 30;
                buttons[i].Text = name;
                buttons[i].Click += Method;
                void Method(object sender2, EventArgs e2) 
                {
                    MessageBox.Show(f); 
                }

                this.Controls.Add(buttons[i]);
                p1.Y += 60;
            }


Демо-видео

Привет!! Я тут до сих пор мучаюсь со своим кодом. По твоему совету сделал и все работает. Но вот проблема: где раньше выводил название файла в MessageBox, я решил открывать файл в браузере(открываю pdf файлы), при первом открытии программы все работает хорошо и на какую кнопку бы я ни нажал открывается нужный файл, но при последующих нажатиях на другие кнопки открываются не нужные файлы, а тот который был открыть первым после запуска программы. Даже ели не убирать MessageBox, то в нем он выводит правильное название файла,  а указав в следующей строке открытия файла в браузере то прога открывает, как я уже сказал, самый первый файл. Если можешь подсказать, то в чем может быть причина??

Добрый день, @godlyman.
Не видя код трудно что-либо подсказать...

Цитата: Adler от 26.01.2021, 20:47

Добрый день, @godlyman.
Не видя код трудно что-либо подсказать...

Сорян! Думал по тому понятно будет..

Спойлер

 Panel browserpanel = new Panel();
this.Controls.Add(browserpane;);
 System.Drawing.Point p1 = new System.Drawing.Point(50,100);
 int count = System.IO.File.ReadAllLines(teoriafile+".txt").Length; // вид файла приложил
 count = count / 2;
 if(count == 0) { }
 else
 {
     int n = File.ReadAllLines(teoriafile+".txt").Length;
     string [] str;
     Button[] buttons = new Button[count];
     using (StreamReader read = new StreamReader(teoriafile+".txt",Encoding.UTF8))
     {
         str = read.ReadToEnd().Split(new char[] { '\n'});
         for (int i =0;i<count;i++)
         {
             if (i < 5) { }
             else { p1.X = 985; if(i==5)p1.Y = 100; }
             string name = str[i*2];
             string file = str[i*2+1];
                 buttons[i] = new Button();
                 buttons[i].Location = new System.Drawing.Point(p1.X, p1.Y);
                 buttons[i].Text = " Кнопка " + (i+1);
                 buttons[i].Click += (s, a) =>
                 {
                     MessageBox.Show(file);
                     browserpanel.Height = this.Height;;
                     browserpanel.Width = this.Width;
                     WebBrowser web = new WebBrowser();
                     web.Navigate(Path.GetFullPath(file));
                     web.Focus();
                 };  
                 p1.Y += 175;
         }
         
     }
 }

Постарался убрать все лишнее
Вид teoriafile: 
//название кнопки 1 
//название pdf файла с расширением 1
//название кнопки 2
//название pdf файла с расширением 2
//название кнопки 3 
//название pdf файла с расширением 3

Файл лежит в Debug, pdf файлы там же. Закинь пару своих если можешь