Компоненты работы с массивами в windows form

Лекция
15

22.0. Массивы в
Windows Forms Application

Массивы – это структура данных,
представляющая собой набор переменных
одинакового типа, имеющих общее имя.

Каждый
элемент массива однозначно определяется
именем и индексом (номером элемента в
массиве). Индексы массива принадлежат
целочисленному типу.

Все
элементы массива имеют одинаковый тип.

Используются
при работе с таблицами и списками.

Массив
может быть:


одномерным,


двумерным /многомерным.

Массивы
различают:

  • статические
    и

  • динамические.

В статическом массиве размеры
массива (верхний индекс элементов)
задаются при объявлении массива (размеры
известны до компиляции программы).

Формат
объявления одномерного массива в C#:

тип[
] ИмяМассива = new
тип [размер];

Формат
объявления двумерного массива в C#:

тип
[ , ] ИмяМассива = new
тип [количество строк, количество
столбцов];

Если массив объявлен с инициализацией
глобально в программе, то начальные
значения элементов массива будут
использоваться во всех процедурах и
обработчиках событий. Пример объявления
массива:

// using – раздел
объявления модулей;

using
System.Windows.Forms;

namespace
WindowsFormsApplication1 //пространство
имен приложения

{

public
partial class Form1 : Form // объявление
класса

{

public Form1()
// объявление формы1

{

InitializeComponent();
// объявление компонент на форме

}

// глобальное объявление массивов

int[] А = new int[5]; // одномерный массив
А из 5 целых чисел

double[,] M = new double[2, 3]; // двумерный массив
M[2х3]

string[ ] Team = {«Zenith»,
«Dynamo», «Sparta», «Rotor», «CSK»};
//строковый

double[] F = { 1.5, 2.1, 3.65, 4.7, 5.14, 6.36 }; // F[6]
из 6 вещественных чисел

int[,] D = { { 0, 2, 4, 6 }, { 2, 9, 6, 3 }, { 4, 7, 5, 8 }, { 1, 6,
5, 7 } }; // массив M [4х4]

}

}

// обработчики событий

Элементы
массива, объявленного глобально
можно инициализировать в процедуре
обработчика события, во время работы
программы, например, для массива A из 5
эл.:

private void
button1_Click(object sender, EventArgs e)

{

// инициализация элементов массива
A, объявленного глобально

A[1] = 5;
A[2] = 6; A[3] = 0; A[4] = -5; A[5]
= -10;

}

Локальный массив объявляется в
процедуре обработчика события, и тогда
его как правило инициализируют во время
исполнения этого события. Значения
элементов, как и сам массив известен
только в этой процедуре. При необходимости
работы с массивом его надо заново
объявлять в другом обработчике события
и производить его инициализацию.
Например:

private
void button2_Click(object sender, EventArgs e)

{

int[] B =
new int[10];
// массив B объявлен
локально

for (int k
= 0; k <= 4; k++)
// с инициализацией элементов

B[k] = k;

}

При обращении к элементам массива
заданного локально в другом обработчике
событий, будет выдано сообщение об
ошибке:

В динамическом массиве при объявлении
указывается имя массива, тип его
элементов, а размер массива определяется
при выполнении программы и задается
некой переменной. Значение переменной
можно ввести в процессе диалога программы
с пользователем или используя свойство
length, содержащее количество элементов,
которое может хранить массив. Например:

private void button1_Click(object sender, EventArgs e)

{

int size = int.Parse(textBox1.Text);
//Задание верхней
границы массива

int []
H = new int[size];

………

}

22.1 Операции с массивами в Windows-приложениях

Типовые операции:

  • вывод/ввод
    массива;

  • поиск
    максимального или минимального элемента
    массива;

  • поиск
    заданного элемента массива;

  • сортировка
    массива.

Ввод-Вывод
массивов в
Windows-приложениях

Поскольку эти приложения позволяют
создать дружелюбный интерфейс
пользователя, то это облегчает работу
по вводу и выводу массивов.

Пример. Форма разделена условно на две
части – для ввода и вывода массива.

Пользователь в текстовое окно число
элементов массива и нажимает командную
кнопку «Создать массив», обработчик
которой создает массив заданной
размерности, если корректно задан
размер, в противном случае выдается
сообщение об ошибки.

Затем пользователь переходит к вводу
элементов массива. Элемент вводится в
текстовое окно, а командная кнопка
«Ввести элемент» обеспечивает передачу
значения в массив. Корректность ввода
контролируется и на этом этапе.

Для облегчения ввода пользователю
выводится подсказка, какой именно
элемент надо ввести. После ввода элементов
массива окно ввода становится недоступным
для ввода элементов.

В нижней части отображается введенный
массив в форме, удобной для восприятия
пользователя. Для этого пригодны
элементы: ListBox, CheckedListBox,
ComboBox. Как только вводится
очередной элемент, он немедленно
отображается во всех объектах.


ComboBox11

label1

label2

label3

label4

label5

label6

label7

listBox1-
список

checkedListBox1

comboBox1-
комбинированный список


textBox1

button1

textBox2

button2

panel1

panel2

Три объекта вывода элементов массива
приведены для демонстрации, реально их
всех отображать не нужно. Компонент
выбирается по желанию пользователя.


using System;

using
System.Collections.Generic;

using
System.ComponentModel;

using System.Data;

using System.Drawing;

using
System.Linq;

using System.Text;

using
System.Windows.Forms;

namespace
WindowsFormsApplication1

{

public partial
class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

double [] mas;

int i=0;

private void
button1_Click(object sender, EventArgs e)

{

try //охраняемый блок


{

int n = int.Parse(textBox1.Text);

mas =
new double[n];

label4.Text = «mas[ » + 0 + » ]»;

textBox2.ReadOnly = false;

listBox1.Items.Clear();

checkedListBox1.Items.Clear();

comboBox1.Items.Clear();

i = 0;

}

catch //перехватчик исключения и
формирование ошибки

{

MessageBox.Show(«Надо вводить цифры «,
«Ошибочный ввод данных»,
MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

private void
button2_Click(object sender, EventArgs e)

{

int n =
int.Parse(textBox1.Text);

mas = new
double[n];
// задание размера массива

mas[i] = double.Parse(textBox2.Text);


label4.Text = «mas[ » + i + » ]»;

listBox1.Items.Add(mas[i]);

checkedListBox1.Items.Add(mas[i]);

comboBox1.Items.Add(mas[i]);

i++;

textBox2.Text = » «;

label6.Text = «ОК»;

if (i == n)

{

label3.Text = » «;

label4.Text = » «;

label6.Text = «Ввод
не доступен
«;

textBox2.Text = » «;

textBox2.ReadOnly = true;

}

}

}

}

Последовательность чисел удобно вводить
в строку таблицы с помощью компонента
DataGridView (данные строкового
вида).

DataGridView – это таблица,
ячейки которой содержат строки символов.


Столбец

Таблица


Строка

Ячейка


Свойства
DataGridView определяют:

Columns
колонки таблицы

Rows
строки таблицы

Cells ячейки

ColumnCount количество
столбцов таблицы

RowCount количество
строк таблицы

Rows[n].Cells[k]
ячейка, лежащая на пересечении n
— го ряда row и k-ой
столбца

Задача1, 2. Ввести
элементы одномерного
массива и вычислить:

Задача1: суммарное, среднеарифметическое,

Задача2: максимальное и минимальное
значения элементов этого массива.

using System;

using
System.Collections.Generic;

using
System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using
System.Windows.Forms;

namespace
WindowsFormsApplication1

{

public partial
class Form1 : Form

{

public Form1()

{

InitializeComponent();
// объявление компонентов на
Form1

}

double[] K =
new double[5]; // объявление
массива

private void
button1_Click(object sender, EventArgs e) // Задача1

{

double avr = 0;
//среднее значение

double summ = 0; //сумма элементов

int n
= 0;
// количество введенных
элементов

try //охраняемый блок

{

for
(int
i
= 0; i
< 5; i++)
//преобразование данных, вводимых в
1 строку

{
// с клавиатуры в цифровой
эквивалент

K[i]
= System.Convert.ToDouble(dataGridView1.Rows[0].Cells[i].Value);

summ
= summ + K[i];

n= n
+ 1;

}

avr =
summ / n;

label1.Text
= «Сумма
элементов:
» + String.Format(«{0,6:f}», summ);

label2.Text
= «Среднее
арифмет.
значение:
» + String.Format(«{0,6:f3}», avr);

}

catch //перехватчик исключения и
формирование ошибки

{

MessageBox.Show(«Надо вводить цифры «,
«Ошибочный ввод данных»,
MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

private void
button2_Click(object sender, EventArgs e) // Задача2

{

double Kmax
= 0;

double Kmin
= 0;

int Nmx =
0;

int Nmn =
0;

try
//охраняемый
блок

{

for
(int
i
= 0; i
< 5; i++)
//преобразование данных, вводимых в
первую строку

{
//с клавиатуры в цифровой эквивалент

K[i]
= System.Convert.ToDouble(dataGridView1.Rows[0].Cells[i].Value);

}

Kmax =
K[0]; // предположение

Nmx =
0;

for
(int i = 1;
i < 5; i++)

{

if (K[i] > Kmax)

{

Kmax
= K[i]; // выявление
max

Nmx = i;

}

}

Kmin =
K[0]; // предположение

Nmn =
0;

for
(int i =1;
i < 5; i++)

{

if
(K[i] < Kmin)

{

Kmin
= K[i]; // выявление
min

Nmn = i;

}

}

label3.Text
= «Максимальное
значение:
» + String.Format(«{0,6:f1}», Kmax) + «, его
номер:
» + Nmx.ToString();

label4.Text
= «Минимальное
значение:
» + String.Format(«{0,6:f1}», Kmin) + «, его
номер:
» + Nmn.ToString();

}

catch //перехватчик исключения и
формирование ошибки

{

MessageBox.Show(«Надо вводить цифры «,
«Ошибочный ввод данных»,
MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

}

}

0
1 2 3 4

Двумерную
таблицу можно представить как совокупность
одномерных массивов.

Задача
3
. Обработать результаты спортивных
соревнований олимпиады.

Программа
должна вычислять общее количество
медалей каждой страны и соответствующее
количество баллов, по правилу:

— за
золотую медаль – 7 баллов,

— за
серебряную медаль – 6 баллов,

— за
бронзовую медаль – 5 баллов,

Устанавливаем на
форму объекты dataGridView1
и button1. Используя свойство
Colomns, создаем коллекцию
столбцов с полями: Страна, Золотых,
Серебряных, Бронзовых, Всего, Баллов


dataGridView

Изменив свойство Name,
переименуем dataGridView в
Tabl.

Количество строк в компоненте
по умолчанию dataGridView
= 1 и для увеличения их численности
необходимо при инициализации элементов
добавить нужное их число через метод
dataGridView.Rows.Add();

public
Form1()

{

InitializeComponent();

Tabl.Rows.Add(8);
//добавление
строк
в
таблицу

}

Заполнение ячеек организовано через
процедуру обработки события Activate,
которое происходит при активизации
формы.

Запуск приложения

При нажатии на кнопку «Итоги» происходит
расчет показателей:

using System;

using
System.Windows.Forms;

namespace
WindowsFormsApplication1

{

public partial
class Form1 : Form

{

public Form1()

{

InitializeComponent();

Tabl.Rows.Add(8);
//добавление
строк
в
таблицу

}

private void
Form1_Activated(object sender, EventArgs e) //при
активизации
формы

{

string[]
Ctrana
= new
string[8]
{ «Австрия», «Великобритания»,
«Германия», «Италия»,

«Россия», «США»,
«Франция», «Япония» };

int[]
Zoloto
= new
int[8]
{ 16, 11, 14, 13, 32, 39, 13, 5 };

int[]
Serebro = new int[8] { 25, 10, 17, 8, 28, 25, 14, 8 };

int[]
Bronza = new int[8] { 17, 7, 28, 13, 28, 33, 11, 5 };

for (int i
= 0; i < 8; i++)

{

Tabl.Rows[i].Cells[0].Value
= Ctrana[i]; // заполнение
элементами
0 столбца

Tabl.Rows[i].Cells[1].Value
= Zoloto[i]; // заполнение
элементами
1 столбца

Tabl.Rows[i].Cells[2].Value
= Serebro[i]; // заполнение
элементами
2 столбца

Tabl.Rows[i].Cells[3].Value
= Bronza[i]; // заполнение
элементами
3 столбца

}

}

private void
button1_Click(object sender, EventArgs e) //кнопка
Итоги

{

int c,r; //номер
колонки и строки Tabl

int s=0; //всего медалей у команды

int b=0; //всего баллов у команды

for (r = 0; r < 8; r++)
//цикл по строкам

{

//вычисление
общего количества медалей

for (c
= 1; c <= 3; c++)

s =
s + System.Convert.ToInt16(Tabl.Rows[r].Cells[c].Value);

//вычисление
общего
количества
баллов

b = 7 *
System.Convert.ToInt16(Tabl.Rows[r].Cells[1].Value) +

6
* System.Convert.ToInt16(Tabl.Rows[r].Cells[2].Value) +

5
* System.Convert.ToInt16(Tabl.Rows[r].Cells[3].Value);

Tabl.Rows[r].Cells[4].Value
= s.ToString(); // всего
медалей
для
каждой
страны

Tabl.Rows[r].Cells[5].Value
= b.ToString(); // всего
баллов
для
каждой
страны

}

}

}

}

Соседние файлы в папке ЛК

  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #

Потому что код срабатывает при условии, что

Тоесть, вы проверяете существует ли CheckBox1 или нет.
У чекбокса есть свойство Checked, которое возвращает true или false, в зависимости от того, поставили галку или нет. Используй это свойство.

А чтобы найти минимальное положительное значение в массиве, нужно организовать цикл так:
Если элемент отрицательный, переходим к следующему элементу

Нужно до цикла объявить временную переменную и присвоить ей значение максимального элемента массива. Проверить, не является ли максимальный элемент отрицательным (В таком случае в массиве нет положительных чисел)А в цикле сравнивать ее с каждым положительным элементом. Если элемент меньше, перезаписать значение временной переменной.

Добавлено через 22 минуты
В итоге должно получится так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 if (checkBox1.Checked)
            {
                int temp = Mas.Max();
                if(temp < 0)
                {
                 textBox3.Text = "В массиве нет положительных чисел";
                }
                else if (temp == 0)
                {
                 textBox3.Text = "Минимальное положительное число в массиве: 0";
                }
                else
                {
                        for (int i = 0; i < Mas.Length; i++)
                         {
                            if (Mas[i] > 0)
                                  { 
                                        if (Mas[i] < temp) temp = Mas[i]
                                  }
                  }
                textBox3.Text = temp.ToString();
            }

Добавлено через 18 минут
Вот рабочий вариант:

Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if (checkBox1.Checked)
            {
                int temp = Mas.Max();
                if (temp < 0)
                {
                    textBox1.Text = "В массиве нет положительных чисел";
                }
                else if (temp == 0)
                {
                    textBox1.Text = "Минимальное положительное число в массиве: 0";
                }
                else
                {
                    for (int i = 0; i < Mas.Length; i++)
                    {
                        if (Mas[i] > 0 && Mas[i] < temp)
                        {
                           temp = Mas[i];
                        }
                    }
                 textBox1.Text = temp.ToString();
                }
                
            }

В данной теме приведен пример разработки приложения типа Windows Forms Application, которое демонстрирует использование списков (класс List) и ассоциативных массивов (класс Dictionary).

Приложение реализует лабораторную работу одного из учебных заведений.

Используя данный пример Вы получите опыт работы с классами Dictionary<TKey,TValue> и List<T>, которые относятся к обобщенным коллекциям.

При разработке приложения реализованы следующие задачи:

  • чтение данных из файла и отображение их в элементе управления типа ListBox;
  • демонстрация использования класса StreamReader из модуля System.IO для чтения данных из файла;
  • демонстрация работы класса Dictionary<TKey, TValue> для организации коллекции. Класс сохраняет пары «ключ-значение»;
  • демонстрация работы класса List<T> для организации динамического массива или списка.

Содержание

  • Условие задачи
  • Выполнение
    • 1. Запустить MS Visual Studio. Создать проект по шаблону Windows Forms Application
    • 2. Создание формы приложения.
    • 3. Настройка свойств элементов управления.
    • 4. Организация данных в виде структур.
    • 5. Классы Dictionary<Key,Value> и List<T>. Описание основных структур данных.
    • 6. Подключение пространства имен System.IO. Класс StreamReader.
    • 7. Программирование методов чтения данных из файлов «Flight.txt» и «Tickets.txt».
    • 8. Изменение кода конструктора формы Form1().
    • 9. Программирование события клика на кнопке «Вычислить».
    • 10. Запуск приложения на выполнение.

Поиск на других ресурсах:

Условие задачи

Реализовать приложение типа Windows Forms Application с использованием списков и ассоциативных массивов.

Дано два текстовых файла: «Flight.txt» и «Tickets.txt«.

Файлы содержат неограниченное количество строк. Каждая строка файла содержит данные, которые разделены символом ‘ , ‘ (запятая).

Одна строка файла «Flight.txt» имеет следующую структуру:

  • номер рейса (целое число);
  • пункт отправки (строка символов);
  • время вылета, часа (целое число);
  • общее количество мест (целое число).

Одна строка файла «Tickets.txt» имеет следующую структуру:

  • номер билета (целое число);
  • номер рейса (целое число);
  • место (целое число);
  • дата вылета (строка символов);
  • пункт назначения (строка символов);
  • дата прибытия (строка символов);
  • время прибытия (целое число);
  • цена (число с плавающей запятой);
  • время продажи билета (строка символов).

В программе нужно решить следующие задачи:

1. Прочитать данные из файла «Flight.txt» и выполнить над ними следующие операции:

  • отобразить их на Windows-форме в элементе управления типа ListBox;
  • организовать данные в коллекцию (класс Dictionary<TKey, TValue>).

2. Прочитать данные из файла «Tickets.txt» и выполнить над ними следующие операции:

  • отобразить их на Windows-форме в элементе управления типа ListBox;
  • организовать данные в динамический массив (класс List<T>).

3. Вывести на форму рейсы с максимальной продолжительностью полета. Вычисление выполнить с использованием классов Dictionary<TKey, TValue> и List<T>.

4. Вывести на форму число пассажиров, которые ждут отправления в введенный момент времени. Вычисление выполнить с использованием классов Dictionary<TKey, TValue> и List<T>.

Пример содержимого файла Flight.txt:

1,Kiev,18,120
2,Kiev ,19,100
3,Kiev,20,90
4,Kiev,22,150

Пример файла «Tickets.txt«:

1,1,1,05.10.2016,California,06.10.2016,21,500,14:10
2,1,1,05.10.2016,California,06.10.2016,21,500,14:30
3,2,1,05.10.2016,Croatia,06.10.2016,22,245,14:45
4,2,2,05.10.2016,Croatia,06.10.2016,22,245,14:50
5,2,3,05.10.2016,Croatia,06.10.2016,22,245,14:51
6,3,1,05.10.2016,Amsterdam,06.10.2016,23,400,14:55
7,3,3,05.10.2016,Amsterdam,06.10.2016,23,400,15:10
8,3,7,05.10.2016,Amsterdam,06.10.2016,23,400,15:25
9,4,1,05.10.2016,Moscow,06.10.2016,24,350,15:27
10,4,10,05.10.2016,Moscow,06.10.2016,24,350,16:08

 

Выполнение

1. Запустить MS Visual Studio.

Создать проект по шаблону C# как Windows Forms Application. Пример создания такого проекта подробно описывается здесь.

 

2. Создание формы приложения.

Разместить на форме следующие элементы управления (рисунок 1):

  • элемент управления типа ListBox для отображения данных из файла «Flights.txt«. Автоматически создается объект с именем listBox1;
  • элемент управления типа ListBox для отображения данных из файла «Tickets.txt«. Автоматически создается объект с именем listBox2;
  • элементы управления типа Label для отображения информационных сообщений. Создаются объекты с именами label1, label2, label3, label4, label5;
  • элемент управления типа TextBox который представляет строку ввода данных (время отправления). Создается объект с именем textBox1;
  • элемент управления типа Button (кнопка «Вычислить«). Создается объект с именем button1;
  • элемент управления типа ListBox (список рейсов с максимальной продолжительностью полетов). Создается объект с именем listBox3.

Скорректировать размеры и позиции элементов управления так как показано на рисунке 1.

C#. Шаблон Windows Forms. Форма приложения Рис. 1. Форма приложения после размещения элементов управления

 

3. Настройка свойств элементов управления.

Настройка свойств элементов управления осуществляется с помощью окна «Properties» системы Microsoft Visual Studio 2010.

Настроить следующие свойства элементов управления:

  • в элементе управления label1 свойство Text = «Файл Flight.txt»;
  • в элементе управления label2 свойство Text = «Файл Tickets.txt»;
  • в элементе управления label3 свойство Text = «Время отправления»;
  • в элементе управления textBox1 свойство Text = «»;
  • в элементе управления label4 свойство Text = «Число пассажиров, которые ждут отправления: «;
  • в элементе управления button1 свойство Text = «Вычислить»;
  • в элементе управления label5 свойство Text = «Рейсы максимальной продолжительностью полета:».

После настройки свойств и корректирования позиций и размеров элементов управления форма приложения будет иметь вид как показано на рисунке 2.

C#. Шаблон Windows Forms. Форма приложения Рис. 2. Форма приложения после настройки элементов управления

 

4. Организация данных в виде структур.

Данные, которые размещаются в одной строке того или иного файла целесообразно представить в виде структуры. Это осуществляется с целью повышения эффективности работы программы. Так как, в отличие от класса, который есть ссылкой, структуры в C# реализованы как типы-значения. В сравнении со структурами, при доступе к объектам класса по ссылке, увеличивается количество выделенных ресурсов и оперативной памяти.



Представим данные одной строки файла «Flight.txt» в виде структуры Flight:

// Структура "Авиарейсы"
public struct Flight
{
    public int num_r; // номер рейса
    public string punkt_vd; // пункт отправления
    public int time_v; // время вылета
    public int n_places; // общее количество мест
}

По тому же принципу представляются данные одной строки файла «Tickets.txt» в структуре Tickets:

// Структура "Билеты"
public struct Tickets
{
    public int num_t; // номер билета
    public int num_r; // номер рейса
    public int place; // место
    public string date_v; // дата вылета
    public string punkt_pr; //пункт назначения
    public string data_pr; // дата прибытия
    public int time_pr; // время прибытия
    public double price; // цена
    public string time_prod; // время продажи билета
}

Фрагмент листинга файла «Form1.cs» после ввода структур имеет следующий вид:

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

namespace Kontrolna_UZHNU_1
{
    public partial class Form1 : Form
    {
        // Структура "Авиарейсы"
        public struct Flight
        {
            public int num_r; // номер рейса
            public string punkt_vd; // пункт отправления
            public int time_v; // время вылета
            public int n_places; // общее количество мест
        }

        public struct Tickets
        {
            public int num_t; // номер билета
            public int num_r; // номер рейса
            public int place; // место
            public string date_v; // дата вылета
            public string punkt_pr; //пункт назначения
            public string data_pr; // дата прибытия
            public int time_pr; // время прибытия
            public double price; // цена
            public string time_prod; // время продажи билета
        }

        public Form1()
        {
            InitializeComponent();
        }
    }
} 

 

5. Классы Dictionary<Key,Value> и List<T>. Описание основных структур данных.

В соответствии с условием задачи, данные, которые размещены в файлах «Flight.txt» и «Tickets.txt«, формируются в коллекции.

Коллекция типа «словарь» (Dictionary) представляется в виде: «ключ-значение». Причем значение ключа есть уникальным (не может повторяться).

Для структуры Flight целесообразно сформировать данные в виде словаря или ассоциированного массива. Это связано с тем, что номер рейса в списке рейсов есть уникальным (не может повторяться).

В C# для представления коллекции типа «словарь» (ассоциированный массив) реализовано два базовых класса:

  • класс HashTable – принадлежит к необобщенным коллекциям;
  • класс Dictionary – принадлежит к обобщенным коллекциям.

В соответствии с условием задачи, нужно использовать класс Dictionary.

Для представления ассоциированного массива в текст класса формы нужно ввести объект с именем avia, что есть типа Dictionary<int, Flight>:

// Ассоциированный массив структур "Авиарейсы"
Dictionary<int, Flight> avia = new Dictionary<int, Flight>();

В этом описании тип int есть номером рейса, а тип Flight есть структурой, которая соответствует этому рейсу.

Для разных рейсов номер билета может повторяться. Поэтому, удобно реализовать билеты в виде обобщенного динамического массива типа List<T>. Вместо типа <T> подставляется структура Tickets – в итоге получается List<Tickets>.

Ввести объект с именем tickets:

// Динамический массив (список) структур "Билеты"
List<Tickets> tickets = new List<Tickets>();

 

6. Подключение пространства имен System.IO. Класс StreamReader.

В соответствии с условием задачи, в программе осуществляется чтение из файла. Библиотека классов .NET Framework представляет множество средств для организации взаимодействия программы с файлами (открытие файла, чтение файла и т.д.).

В данной работе использованы возможности класса StreamReader. Этот класс описывается в просторные имен System.IO. Итак, в начале файла «Form1.cs» нужно ввести строку:

using System.IO;

Класс StreamReader предназначен для ввода символов из байтового потока. Для вывода символов в байтовый поток используется класс StreamWriter.

В классе StreamReader есть метод ReadLine(), читающий текстовую строку из файла. Метод ReadLine() возвращает строку типа string. Этот метод будет использован при чтении файла в данной задаче.

 

7. Программирование методов чтения данных из файлов «Flight.txt» и «Tickets.txt«.

Прочитанные из файлов «Flight.txt» и «Tickets.txt» данные отображаются в элементах управления listBox1 и listBox2. Для отображения данных нужно создать два метода.

Первый метод Read_Avia() выполняет следующие операции:

  • читает список авиарейсов из файла «Flight.txt«;
  • формирует ассоциированный массив avia типа Dictionary<int, Flight>;
  • формирует список авиарейсов в listBox1 для его отображения на форме.

Второй метод Read_Tickets() выполняет следующие операции:

  • читает перечень купленных билетов из файла «Tickets.txt«;
  • формирует динамический массив tickets типа List<Tickets>;
  • выводит содержимое файла «Tickets.txt» в listBox2.

Листинг методов Read_Avia() и Read_Tickets() следующий:

public void Read_Avia()
{
  StreamReader sr = new StreamReader("Flight.txt", Encoding.Default);
  string s = "";
  string[] fields;
  Flight sa; // дополнительная переменная - структура типа Flight

  // Основной цикл.
  // В цикле:
  // 1. Читаются данные из файла "Flight.txt"
  // 2. Формируется словарь avia типа Dictionary<int, Flight>

  while (s != null)
  {
    s = sr.ReadLine(); // прочитать строку из файла
    if (s != null)
    {
      fields = s.Split(',');
      // формирование структуры sa типа struct Flight
      sa.num_r = Convert.ToInt32(fields[0]);
      sa.punkt_vd = fields[1];
      sa.time_v = Convert.ToInt32(fields[2]);
      sa.n_places = Convert.ToInt32(fields[3]);

      // добавляем пару <num_r, sa> в словарь avia
      // ключом к структуре есть номер рейса num_r
      avia.Add(sa.num_r, sa);

      // добавить строку s в listBox1
      listBox1.Items.Add(s);
    }
  }
}

public void Read_Tickets()
{
  StreamReader sr = new StreamReader("Tickets.txt", Encoding.Default);
  string s;
  string[] fields; // массив строк-полей структуры Tickets
  Tickets tk; // вспомогательная переменная-структура

  s = sr.ReadLine();

  // Основной цикл.
  // В цикле:
  // 1. Читаются данные из файла "Tickets.txt"
  // 2. Формируется список tickets типа List<Tickets>

  // используем цикл do...while()
  do
  {
    // разбить строку s на части по признаку символа ','
    fields = s.Split(',');

    // заполнить структуру tk
    tk.num_t = Convert.ToInt32(fields[0]);
    tk.num_r = Convert.ToInt32(fields[1]);
    tk.place = Convert.ToInt32(fields[2]);
    tk.date_v = fields[3];
    tk.punkt_pr = fields[4];
    tk.data_pr = fields[5];
    tk.time_pr = Convert.ToInt32(fields[6]);
    tk.price = Convert.ToDouble(fields[7]);
    tk.time_prod = fields[8];

    // добавить заполненную структуру в список tickets
    tickets.Add(tk);

    listBox2.Items.Add(s);
    s = sr.ReadLine();
  }
  while (s != null);
}

Объясним некоторые фрагменты кода в методах Read_Avia() и Read_Tickets().

Чтение файла осуществляется с помощью класса StreamReader, который предназначен для ввода символов из байтового потока. Открытие файлов реализуется в конструкторе класса StreamReader:

StreamReader sr = new StreamReader("Flight.txt", Encoding.Default);
StreamReader sr = new StreamReader("Tickets.txt", Encoding.Default);

Чтение строки из файла осуществляется методом ReadLine() класса StreamReader. Если достигнут конец файла, то метод возвращает null.

С помощью строки

fields = s.Split(',');

происходит разделение строки на составные части. Разделитель между составными частями – это символ ‘ , ‘.

Строка

avia.Add(sa.num_r, sa);

добавляет в коллекцию avia типа Dictionary<int, Flight> номер рейса и заполненную структуру sa.

Строка

tickets.Add(tk);

добавляет в коллекцию tk типа List<Tickets> структуру tk.

 

8. Изменение кода конструктора формы Form1().

Методы Read_Avia() и Read_Tickets() размещаются в конструкторе формы Form1().

Листинг конструктора формы Form1() следующий:

public Form1()
{
    InitializeComponent();
    Read_Avia();
    Read_Tickets();
}

 

9. Программирование события клика на кнопке «Вычислить«.

Листинг обработчика события клика на кнопке «Вычислить» имеет вид:

private void button1_Click(object sender, EventArgs e)
{
  // Расчет
  // 1. Рейсы с максимальной продолжительностью полета
  int i, j;
  int max, tmp;
  bool f_first = true;

  max = 0;

  foreach (var a in avia)
  {
    foreach (var t in tickets)
      if (a.Value.num_r == t.num_r)
      {
        if (f_first)
        {
          max = t.time_pr - a.Value.time_v;
          f_first = false;
        }
        else
        {
          tmp = t.time_pr - a.Value.time_v;
          if (max < tmp) max = tmp;
        }
      }
  } // на выходе получаем максимальную длительность полета в переменной max

  // формирование списка рейсов с максимальной продолжительностью полета
  listBox3.Items.Clear();

  foreach (var a in avia)
  {
    foreach (var t in tickets)
      if (a.Value.num_r == t.num_r)
      {
        tmp = t.time_pr - a.Value.time_v;
        if (tmp == max)
        {
          string s;
          s = a.Value.num_r.ToString() + ", " +
              a.Value.punkt_vd + ", " +
              a.Value.time_v.ToString() + ", " +
              a.Value.n_places.ToString() + " - " +
              t.num_t.ToString() + ", " +
              t.punkt_pr + ", " +
              t.time_pr.ToString() + ", " +
              t.place.ToString();

              listBox3.Items.Add(s);
        }
      }
  }

  label4.Text = "Рейсы с максимальной продолжительностью полета: " + max.ToString();

  // 2. Число пассажиров, которые ждут отправления в введенный момент времени
  int tm, k;

  tm = Int32.Parse(textBox1.Text); // получить время
  k = 0; // число пассажиров
  foreach (var a in avia)
  {
    foreach (var t in tickets)
      if ((a.Value.num_r == t.num_r)&&(tm==a.Value.time_v))
        k++;
  }

  label5.Text = "Число пассажиров, которые ждут отправления: " + k.ToString();
}

В вышеприведенном листинге следует отметить. При просмотре коллекций используется оператор foreach (и только foreach). Оператор foreach служит для циклического обращения к элементам коллекции, которая представляет собой группу объектов. Использование других операторов цикла приводит к ошибке.

Список рейсов с максимальной продолжительностью полета выводится в элемент управления listBox3.

 

10. Запуск приложения на выполнение.

Результат работы приложения изображен на рисунке 3.

C#. Шаблон Windows Forms. Выполнение приложения работы со списками Рис. 3. Результат работы приложения

 


Массивы массивов

Еще одним видом массивов C# являются массивы массивов, называемые также изрезанными массивами (jagged arrays). Такой массив массивов можно рассматривать как одномерный массив, его элементы являются массивами, элементы которых, в свою очередь снова могут быть массивами, и так может продолжаться до некоторого уровня вложенности.

В каких ситуациях может возникать необходимость в таких структурах данных? Эти массивы могут применяться для представления деревьев, у которых узлы могут иметь произвольное число потомков. Таковым может быть, например, генеалогическое дерево. Вершины первого уровня — Fathers, представляющие отцов, могут задаваться одномерным массивом, так что Fathers[i] — это i-й отец. Вершины второго уровня представляются массивом массивов — Children, так что Children[i] — это массив детей i-го отца, а Children[i][j] — это j-й ребенок i-го отца. Для представления внуков понадобится третий уровень, так что GrandChildren [i][j][k] будет представлять к-го внука j-го ребенка i-го отца.

Есть некоторые особенности в объявлении и инициализации таких массивов. Если при объявлении типа многомерных массивов для указания размерности использовались запятые, то для изрезанных массивов применяется более ясная символика — совокупности пар квадратных скобок; например, int[][] задает массив, элементы которого — одномерные массивы элементов типа int.

Сложнее с созданием самих массивов и их инициализацией. Здесь нельзя вызвать конструктор new int[3][5], поскольку он не задает изрезанный массив. Фактически нужно вызывать конструктор для каждого массива на самом нижнем уровне. В этом и состоит сложность объявления таких массивов. Начну с формального примера:

//массив массивов - формальный пример
   	//объявление и инициализация
  	int[][] jagger = new int[3][]
  {
        new int[] {5,7,9,11},
        new int[] {2,8},
        new int[] {6,12,4}
  };

Массив jagger имеет всего два уровня. Можно считать, что у него три элемента, каждый из которых является массивом. Для каждого такого массива необходимо вызвать конструктор new, чтобы создать внутренний массив. В данном примере элементы внутренних массивов получают значение, будучи явно инициализированы константными массивами. Конечно, допустимо и такое объявление:

int[][] jagger1 = new int[3][]
  {
  new int[4],
  new int[2],
  new int[3]
  };

В этом случае элементы массива получат при инициализации нулевые значения. Реальную инициализацию нужно будет выполнять программным путем. Стоит заметить, что в конструкторе верхнего уровня константу 3 можно опустить и писать просто new int[][]. Самое забавное, что вызов этого конструктора можно вообще опустить, он будет подразумеваться:

int[][] jagger2 =
   {
  new int[4],
  new int[2],
  new int[3]
  };

Но вот конструкторы нижнего уровня необходимы. Еще одно важное замечание — динамические массивы возможны и здесь. В общем случае, границы на любом уровне могут быть выражениями, зависящими от переменных. Более того, допустимо, чтобы массивы на нижнем уровне были многомерными. Но это уже «от лукавого», вряд ли стоит пользоваться такими сложными структурами данных, ведь с ними предстоит еще и работать.

Приведу теперь чуть более реальный пример, описывающий простое генеалогическое дерево, которое условно назову «отцы и дети»:

/// <summary>
/// массив массивов -"Отцы и дети"
/// </summary>
public void GenTree()
 {            
    int Fcount = 3;
    string[] Fathers = new string[Fcount];
    Fathers[0] = "Николай"; Fathers[1] = "Сергей"; Fathers[2] = "Петр";
    string[][] Children = new string[Fcount][];
    Children[0] = new string[] {"Ольга", "Федор"};
    Children[1] = new string[] {"Сергей", "Валентина", "Ира", "Дмитрий"};
    Children[2] = new string[] {"Мария", "Ирина", "Надежда"};
    Arrs.PrintAr3(Fathers, Children);
  }

Здесь отцов описывает обычный динамический одномерный массив Fathers. Для описания детей этих отцов необходим уже массив массивов, который также является динамическим на верхнем уровне, поскольку число его элементов совпадает с числом элементов массива Fathers. Здесь показан еще один способ создания таких массивов. Вначале конструируется массив верхнего уровня, содержащий ссылки со значением void. А затем на нижнем уровне конструктор создает настоящие массивы в динамической памяти, с которыми и связываются ссылки.

Я не буду демонстрировать работу с генеалогическим деревом, ограничусь лишь печатью этого массива. Здесь есть несколько поучительных моментов. В классе Arrs для печати массива создан специальный метод PrintAr3, которому в качестве аргументов передаются массивы Fathers и Children. Вот текст данной процедуры:

/// <summary>
        /// Печать дерева "Отцы и дети",
        /// заданного массивами Fathers и Children
        /// </summary>
        /// <param name="Fathers">массив отцов</param>
        /// <param name="Children"> массив массивов детей</param>
        public static void PrintAr3(string[] Fathers, string[][] Children)
        {
            for (int i = 0; i < Fathers.Length; i++)
            {
                Console.WriteLine("Отец : {0}; Его дети:", Fathers[i]);
                for (int j = 0; j < Children[i].Length; j++)
                    Console.Write(Children[i][j] + " ");
                Console.WriteLine();
            }
        }//PrintAr3

Приведу некоторые комментарии к этой процедуре.

  • Внешний цикл по i организован по числу элементов массива Fathers. Заметьте, здесь используется свойство Length, в отличие от ранее применяемого метода GetLength.
  • В этом цикле с тем же успехом можно было бы использовать и имя массива Children. Свойство Length для него возвращает число элементов верхнего уровня, совпадающее, как уже говорилось, с числом элементов массива Fathers.
  • Во внутреннем цикле свойство Length вызывается для каждого элемента Children[i], который является массивом.
  • Остальные детали, надеюсь, понятны.

Приведу вывод, полученный в результате работы процедуры PrintAr3.

Дерево "Отцы и дети"

Рис.
6.3.
Дерево «Отцы и дети»

Процедуры и массивы

В наших примерах массивы неоднократно передавались процедурам в качестве входных аргументов и возвращались в качестве результатов. Остается подчеркнуть только некоторые детали.

  • В процедуру достаточно передавать только сам объект — массив. Все его характеристики (размерность, границы) можно определить, используя свойства и методы этого объекта.
  • Когда массив является выходным аргументом процедуры, как аргумент C в процедуре MultMatr, выходной аргумент совсем не обязательно снабжать ключевым словом ref или out (хотя и допустимо). Передача аргумента по значению в таких ситуациях так же хороша, как и передача по ссылке. В результате вычислений меняется сам массив в динамической памяти, а ссылка на него остается постоянной. Процедура и ее вызов без ключевых слов выглядит проще, поэтому обычно они опускаются. Заметьте, в процедуре GetSizes, где определялись границы массива, ключевое слово out, сопровождающее аргументы, совершенно необходимо.
  • Функция может возвращать массив в качестве результата.

Алгоритмы и задачи

Алгоритмы и задачи, рассматриваемые в этой главе, являются частью фундамента, на котором строится образование программиста. Нет ни одной проблемной области, в задачах которой не требовались бы массивы. Поэтому задачи, требующие использования массивов, появлялись уже в предыдущих главах, появятся они и в последующих. Но здесь мы будем заниматься ими целенаправленно.

Последовательность элементов — a_1, a_2, \ldots a_n — одна из любимых структур в математике. Последовательность можно рассматривать как функцию a(i), которая по заданному значению индекса элемента возвращает его значение. Эта функция задает отображение integer -> T, где T — это тип элементов последовательности. В программировании последовательности это одномерные массивы, но от этого они не перестают быть менее любимыми.

Определение. Массив — это упорядоченная последовательность элементов одного типа. Порядок элементов задается с помощью индексов.

В отличие от математики, где последовательность может быть бесконечной, массивы всегда имеют конечное число элементов. Для программистов важно то, как массивы хранятся в памяти. Массивы занимают непрерывную область памяти, поэтому, зная адрес начального элемента массива, зная, сколько байтов памяти требуется для хранения одного элемента, и зная индекс (индексы) некоторого элемента, нетрудно вычислить его адрес, а значит, и хранимое по этому адресу значение элемента. На этом основана адресная арифметика в языках C и C++, где адрес элемента a(i) задается адресным выражением a+i, в котором имя массива a воспринимается как адрес первого элемента. При вычислении адреса i-го элемента индекс i умножается на длину слова, требуемого для хранения элементов типа T. Адресная арифметика использует 0-базируемость элементов массива, полагая индекс первого элемента равным нулю, поскольку первому элементу соответствует адресное выражение а+0.

Язык C# сохранил 0-базируемость массивов. Индексы элементов массива в языке C# изменяются в плотном интервале значений от нижней границы, всегда равной 0, до верхней границы, которая задана динамически вычисляемым выражением, возможно, зависящим от переменных. Массивы C# являются 0-базируемыми динамическими массивами. Это важно понимать с самого начала.

Не менее важно понимать и то, что массивы C# относятся к ссылочным типам.

Ввод-вывод массивов

Как у массивов появляются значения, как они изменяются? Возможны три основных способа:

  • вычисление значений в программе;
  • значения вводит пользователь;
  • связывание с источником данных.

В задачах этого раздела ограничимся пока рассмотрением первых двух способов. Первый способ более или менее понятен. Простые примеры его применения приводились неоднократно. Стоит только отметить, что в классе, работающем с массивами, всегда полезно иметь метод FillArray, позволяющий заполнять массив случайными числами. В примерах использование возможностей класса Random для моделирования элементов массива встречалось неоднократно.

Приведу некоторые рекомендации по вводу и выводу массивов, ориентированные на работу с конечным пользователем.

Для консольных приложений ввод массива обычно проходит несколько этапов:

  • ввод размеров массива;
  • создание массива;
  • организация цикла по числу элементов массива, в теле которого выполняется:
    • приглашение к вводу очередного элемента;
    • ввод элемента;
    • проверка корректности введенного значения.

Вначале у пользователя запрашиваются размеры массива, затем создается массив заданного размера. В цикле по числу элементов организуется ввод значений. Вводу каждого значения предшествует приглашение к вводу с указанием типа вводимого значения, а при необходимости — и диапазона, в котором должно находиться требуемое значение. Поскольку ввод значений — это ответственная операция, а на пользователя никогда нельзя положиться, после ввода часто организуется проверка корректности введенного значения. При некорректном задании значения элемента ввод повторяется, пока не будет достигнут желаемый результат.

При выводе массива на консоль обычно вначале выводится имя массива, а затем его элементы в виде пары: <имя> = <значение> (например, f[5] = 77,7). Задача осложняется для многомерных массивов, когда пользователю важно видеть не только значения, но и структуру массива, располагая строку массива в строке экрана.

Как организовать контроль ввода? Наиболее разумно использовать для этих целей конструкцию охраняемых блоков — try — catch блоков. Это общий подход, когда все опасные действия, связанные с работой пользователя, внешних устройств, внешних источников данных, размещаются в охраняемых блоках.

Как правило, для ввода-вывода массивов пишутся специальные процедуры, вызываемые в нужный момент.

Ввод-вывод массивов в Windows-приложениях

Приложения Windows позволяют построить дружелюбный интерфейс пользователя, облегчающий работу по вводу и выводу массивов. И здесь, когда данные задаются пользователем, заполнение массива проходит через те же этапы, что рассматривались для консольных приложений. Но выглядит все это более красиво, наглядно и понятно. Пример подобного интерфейса, обеспечивающего работу по вводу и выводу одномерного массива, показан на
рис.
6.4.

Форма для ввода-вывода одномерного массива

Рис.
6.4.
Форма для ввода-вывода одномерного массива

Пользователь вводит в текстовое окно число элементов массива и нажимает командную кнопку «Создать массив», обработчик которой создает массив заданной размерности, если корректно задан размер массива, в противном случае выдает сообщение об ошибке и ждет корректного ввода.

В случае успешного создания массива пользователь может переходить к следующему этапу — вводу элементов массива. Очередной элемент массива вводится в текстовое окно, а обработчик командной кнопки «Ввести элемент» обеспечивает передачу значения в массив. Корректность ввода контролируется и на этом этапе, проверяя значение введенного элемента и выводя в специальное окно сообщение в случае его некорректности, добиваясь, в конечном итоге, получения от пользователя корректного ввода.

Для облегчения работы пользователя выводится подсказка, какой именно элемент должен вводить пользователь. После того, как все элементы массива введены, окно ввода становится недоступным для ввода элементов. Интерфейс формы позволяет многократно создавать новый массив, повторяя весь процесс.

На
рис.
6.4 форма разделена на две части — для ввода и вывода массива. Крайне важно уметь организовать ввод массива, принимая данные от пользователя. Не менее важно уметь отображать существующий массив в форме, удобной для восприятия пользователя. На рисунке показаны три различных элемента управления, пригодные для этих целей, — ListBox, CheckedListBox и ComboBox. Как только вводится очередной элемент, он немедленно отображается во всех трех списках.

В реальности отображать массив в трех списках, конечно, не нужно, это сделано только в целях демонстрации возможностей различных элементов управления. Для целей вывода подходит любой из них, выбор зависит от контекста и предпочтений пользователя. Элемент ComboBox имеет дополнительное текстовое окно, в которое пользователь может вводить значение. Элемент CheckedListBox обладает дополнительными свойствами в сравнении с элементом ListBox, позволяя отмечать некоторые элементы списка (массива). Отмеченные пользователем элементы составляют специальную коллекцию. Эта коллекция доступна, с ней можно работать, что иногда весьма полезно. Чаще всего для вывода массива используется элемент ListBox.

Посмотрим, как это все организовано программно. Начну с полей формы OneDimArrayForm, показанной на
рис.
6.4:

//fields
  int n = 0;
  double[] mas;
  int currentindex = 0;  
  double ditem = 0;
  const string SIZE = "Корректно задайте размер массива!";
  const string INVITE = "Введите число в формате m[,n]";
  const string EMPTY =  "Массив пуст!";
  const string ITEMB =  "mas[";
  const string ITEME =  "] = ";
  const string FULL =   "Ввод недоступен!";
  const string OK =     "Корректный ввод!";
  const string ERR =    "Ошибка ввода числа! Повторите ввод!";

Полями этого класса является одномерный массив, его размер, текущий индекс и константы, используемые в процессе диалога с пользователем. Обработчик события Click командной кнопки, отвечающей за создание массива, имеет вид:

private void buttonCreateArray_Click(object sender, EventArgs e)
  {
      try
      {
    n = Convert.ToInt32(textBoxN.Text);
    mas = new double[n]; 
    labelInvite.Text = INVITE;
    labelItem.Text = ITEMB + "0" + ITEME;
    labelResult.Text = EMPTY;
    textBoxItem.ReadOnly = false;
    listBox1.Items.Clear();
    comboBox1.Items.Clear();
    checkedListBox1.Items.Clear();
    comboBox1.Items.Clear();
    currentindex = 0;
      }
      catch (Exception)
      {
    labelResult.Text = SIZE;
      }
  }

Первым делом принимается размер массива, введенный пользователем. Преобразование к типу int введенного значения помещено в охраняемый блок, поэтому ошибки некорректного ввода будут перехвачены с выдачей соответствующего сообщения. Если же массив успешно создан, то инициализируются начальными значениями все элементы интерфейса, участвующие в вводе элементов массива. Рассмотрим, как устроен ввод элементов.

private void buttonAddItem_Click(object sender, EventArgs e)
  {
      //Заполнение массива элементами
      if (GetItem())
      {
    mas[currentindex] = ditem;
    listBox1.Items.Add(mas[currentindex]);
    checkedListBox1.Items.Add(mas[currentindex]);
    comboBox1.Items.Add(mas[currentindex]);
    currentindex++;
    labelItem.Text = ITEMB + currentindex + ITEME;
    textBoxItem.Text = "";
    labelResult.Text = OK;
    if (currentindex == n)
    {
        labelInvite.Text = "";
        labelItem.Text = "";
        labelResult.Text = FULL;
        textBoxItem.Text = "";
        textBoxItem.ReadOnly = true;
    }
   }
}

Функция GetItem вводит значение очередного элемента. Если пользователь корректно задал его значение, то элемент добавляется в массив, а заодно и в списки, отображающие текущее состояние массива. Создается подсказка для ввода следующего элемента массива, а если массив полностью определен, то форма переходит в состояние окончания ввода.

/// <summary>
   /// Ввод с контролем текущего элемента массива
   /// </summary>
   /// <returns>true в случае корректного ввода значения</returns>
   bool GetItem()
   {
       string item = textBoxItem.Text;
       bool res = false;
       if (item == "")
      labelResult.Text = INVITE;
       else
       {
      try
      {
          ditem = Convert.ToDouble(item);
          res = true;
      }
      catch(Exception)
      {
          labelResult.Text = ERR;
      }
       }
       return res;
   }

Форму OneDimArrayForm можно рассматривать как некоторый шаблон, полезный при организации ввода и вывода одномерных массивов.

Для ввода элементов использую DataGridView. Посмотрел множество примеров использования, но когда пытаюсь сделать что-то в собственном коде, при отладке сам компонент DataGridView представляется в виде серого прямоугольника без каких-либо столбцов и строк. В качестве источника данных этот компонент видит только главную форму программы Form1. Что необходимо отредактировать в списке свойств и добавить в код, чтобы была возможность ввести элементы и считать их?

На примере ввода массива с дальнейшей его обработкой (arrayGrid — объект DataGridView):

private void button1_Click(object sender, EventArgs e)
    {
        arrayGrid.RowCount = 1;
        arrayGrid.ColumnCount = SIZE;

        arrayGrid.Rows.Add();
        for (int i = 0; i < SIZE; i++)
            arrayGrid.Columns.Add("column" + i.ToString(), i.ToString());

        for (int i = 0; i < SIZE; i++)
            arr[i] = int.Parse((string)arrayGrid.Rows[0].Cells[i].Value);

        int min = arr[0];

        for (int i = 1; i < SIZE; i++)
            if (arr[i] < min)
                min = arr[i];

        label3.Text = min.ToString();
    }

задан 28 сен 2017 в 18:37

zergon321's user avatar

Один из самых простых способов — использовать DataTable.

dataTable = new DataTable();

// Количество столбцов
for (int i = 0; i < 3; i++)
    dataTable.Columns.Add(i.ToString(), typeof(int)); // укажите нужный тип данных матрицы

// Количество строк
for (int i = 0; i < 3; i++)
    dataTable.Rows.Add(dataTable.NewRow());

dataGridView.DataSource = dataTable;

// Опции по желанию
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView.AllowUserToAddRows = false;

Далее, соответственно, вместо массива работайте в коде с DataTable.

К отдельным элементам можно обращаться следующим образом:

dataTable.Rows[0][0]

ответ дан 28 сен 2017 в 19:49

Alexander Petrov's user avatar

Alexander PetrovAlexander Petrov

28.8k5 золотых знаков28 серебряных знаков55 бронзовых знаков

  • Компоненты visual c для windows 10 64 bit
  • Компьютер видит клавиатуру но она не работает windows 10
  • Компоненты по запросу windows 10
  • Компилятор языка си для windows
  • Компонент платформа виртуальной машины windows 10 что это