powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как ускорить работу кода?
27 сообщений из 27, показаны все 2 страниц
Как ускорить работу кода?
    #38690946
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Существует проект(написан еще до меня на C#).
загружается фотография(работает фоном).
По размеру фотографии поелементно создается матрица 20x20 из UserControl-компонентов.

на компоненте:
public System.Windows.Forms.Panel pnMain;
public System.Windows.Forms.Label lblText;

Очень долго загружается(у меня проц і5, а на производстве вообще мрак)

Как ускорить работу кода?
Можно переписать код, но принцып изменить немугу, там завязано много на этот принцып.
Код процедуры:
Код: 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.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
public static void CreateSections(PictureBox pbMain, IDictionary<string, string> dic, int cellCountRows = 20, int cellCountColumns =20 ) {
	Size sz = getZoomedImage(pbMain);

	double width = sz.Width;
	double height = sz.Height;

	if (width % 10 > 0)
		width = Math.Round(width / 10) * 10;

	if (height % 10 > 0)
		height = Math.Round(height / 10) * 10;

	float widthOneComponent = sz.Width / cellCountColumns;
	float heightOneComponent = sz.Height / cellCountRows;

	int v_begin = (pbMain.ClientSize.Height - sz.Height) / 2;
	int h_begin = (pbMain.ClientSize.Width - sz.Width) / 2;

	int v = v_begin;
	int h = h_begin;
	
	int number = 1;
	pbMain.Visible = false;

	while ((v + heightOneComponent - (heightOneComponent / 2)) < (height + v_begin)) {
		
		while ((h + widthOneComponent - (widthOneComponent / 2)) < (width + h_begin)) {
			Cell r = new Cell();
			r.Name = "VisComponent" + number;
			r.Top = v;
			r.Left = h;
			r.Height = Convert.ToInt32(heightOneComponent);
			r.Width = Convert.ToInt32(widthOneComponent);

			r.pnMain.Click += delegate(object o, EventArgs e) {
				using (SqlConnection con = new SqlConnection(ConnStr)) {
					r.lblText.Visible = true;
					r.lblText.ForeColor = Color.Red;
					r.lblText.BackColor = Color.Red;

					con.Open();
					string sql = " insert into tbl_Transaction(AssmID, Position, LastUpdate) " +
									" values(@AssmID, @Position, GETDATE()) ";
					using (SqlCommand com = new SqlCommand(sql, con)) {
						com.Parameters.Add("@AssmID", dic["id"]);
						com.Parameters.Add("@Position", r.lblText.Text);
						com.ExecuteNonQuery();
					}
				}

				System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
				timer.Interval = 1000;
				timer.Tick += (source, u) => { r.lblText.Visible = false; timer.Stop(); };
				timer.Start();
			};

			r.BorderStyle = BorderStyle.None;
			r.lblText.Text = number.ToString();
			r.lblText.Left = 0;
			r.lblText.Top = 0;
			r.lblText.ForeColor = Color.White;
			r.lblText.BackColor = Color.Black;
			r.lblText.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			//-----
			r.lblText.Visible = false;

			pbMain.Controls.Add(r);

			number += 1;
			h += Convert.ToInt32(widthOneComponent);
		}
		
		v += Convert.ToInt32(heightOneComponent);
		h = 0;
		
	}

	pbMain.Visible = true;
}


Спасибо за внимание!
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691005
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
нечего тут оптимизировать... может ежли только не pbMain.Controls.Add(r); а сперва создать массив и вкрячить его в конце через pbMain.Controls.AddRange(...)

И delegate(object o, EventArgs e) {
...
};

Опишите отдельно... просто громоздко... как-то...
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691027
petalvik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko,

O_O
Жуть! 400 запросов к БД!
На каждой итерации таймер создаётся и запускается...


Частично можно оптимизировать, если создать все используемые контролы один раз, например, при запуске программы. То есть сделать их полями, а не локальными переменными.

Должен быть всего один запрос к БД.

Возможно, чуть помогут вызовы методов SuspendLayout() и ResumeLayout() в начале и конце соответственно.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691030
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko,

20x20 из UserControl-компонентов - выбросить нахер компоненты

тексты и фон рисовать поверх картинки , клики мыши отрабатывать на картинке.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691031
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petalvikЖуть! 400 запросов к БД!
На каждой итерации таймер создаётся и запускается...


не на итерации, а по клику
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691033
petalvik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, таймер по клику запускается. Сразу не разглядел.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691113
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko, поставь вместо pbMain.Visible = false; вызов pbMain.SuspendLayout();
А вместо pbMain.Visible = true; соответственнно вызов pbMain.ResumeLayout();

Также следует избавиться от анонимной функции и заменить её на обычную функцию. В коде используется захват локальной переменной r. Чтобы код откомпилировался нужно добавить в начале функции следующую строку:
Код: c#
1.
Cell r = (Cell)(((Control)o).Parent);


Здесь предполагается что Cell является родителем для кнопки. Если есть еще один или несколько уровней вложенности, то не составит труда написать extension функцию FindParent<T> для класса Control которая найдет родителя нужного типа.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691310
Фотография Василий Викторович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko,

1) разделение логики и интерфейса, вспоминаем парадигму MVC, т. е. посреди настройки внешнего вида не должен быть код работающий с данными
2) вынести sql в отдельную процедуру на ms sql сервер -> оптимизация sql кода, пайджинг на стороне ms sql server'a и все такое
3) 2 сторонний databinding на основе механизмов NET

После этого можно подумать дальше
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691333
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий ВикторовичSNenko,

1) разделение логики и интерфейса, вспоминаем парадигму MVC, т. е. посреди настройки внешнего вида не должен быть код работающий с данными
2) вынести sql в отдельную процедуру на ms sql сервер -> оптимизация sql кода, пайджинг на стороне ms sql server'a и все такое
3) 2 сторонний databinding на основе механизмов NET

После этого можно подумать дальше
Все бы ничего, только к коду топикстартера это имеет мало отношения
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691349
Фотография Василий Викторович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,

Вот мне интересно откуда вы взяли что эти рекомендации не помогут? как минимум я тут вижу код требующий рефакторинга, правда истинное название этого немного другое ну да ладно,
1) MVC - причины: котлеты отдельно мухи отдельно, т. е. разнести как минимум настройку интерфейса и обращение к БД в 2 разные функции, именно функции а не реализованный в середине функции анонимный делегат
2) Sql, голый sql запрос выдает с головой уровень писавшего это, как минимум обвернуть это в хранимую процедуру и ее дергать о технологиях ОRM и иже с ними я промолчу, о пайдженге на стороне сервера чтобы не тянуть тысячи записей тоже
3) ручное создание ячеек как минимум дурно пахнет так как уже давным - давно применяют DataBindings колекций обьектов к элементам интерфейса причем биндинг является двух сторонним со всякими интересными плюшками в виде генераций подтаблиц и валидаторов пользовательского ввода

P. S. код - результат человека только начавшего делать первые шаги в освоении языка и по этому допускающего определенные детские промахи, это исправимо, года через 1,5 после того как наберется опыта
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691373
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий ВикторовичВот мне интересно откуда вы взяли что эти рекомендации не помогут?
Вы, не читая кода, дали абстрактные советы

1) анонимный делегат вызывается только при клике мышью - на быстродействие никак не влияет
2) SQL запрос - простое добавление записи, запрос с параметрами - всё в порядке.
какой тут пейджинг и ORM? (что характерно - тоже по клику вызывается)
3)проблема здесь не в в отсутствии байндинга, а в создании сотен контролов

достаточно рисовать текст непосредственно поверх картинки и клики отрабатывать на картинке
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691488
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Говоря о мухах и котлаетах, вы безусловно правы.

Почищу код и выложу результат
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692055
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Быстрее работать не стало, но уменьшилось количество неточностей.

Щас закину в масив. Использу pbMain.Controls.AddRange(...).
Но это для порядка.
Не думаю что поможет..
Буду делать обработку кликов на картинке pbMain.
Спасибо за советы.

Выложу потом следюущий код.

это процедура:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
public static void CreateSections(PictureBox pbMain, IDictionary<string, string> dic, int cellCountRows = 20, int cellCountColumns =20 )
{
	pbMain.SuspendLayout();
	
	MyImage image = new MyImage(pbMain);
	MyCell cell = new MyCell(image, cellCountRows, cellCountColumns);
	MyCurrentCellPosition curr = new MyCurrentCellPosition(image, cell);
	
	for (int y = 1; y <= cellCountRows; y++)
	{
		for (int x = 1; x <= cellCountColumns; x++)
		{
			Cell r = new Cell(x*y, curr.y, curr.x, cell.size, dic["id"], ConnStr);
			pbMain.Controls.Add(r);
			curr.NewCell();
		}
		curr.NewRow();
	}
	pbMain.ResumeLayout();
}


А это класы к ней:

Код: 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.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
        class MyImage
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
            public Size size;

            public MyImage(PictureBox pbMain)
            {
                this.size = getZoomedImage(pbMain);
                this.Left = (pbMain.ClientSize.Width - size.Width) / 2;
                this.Top = (pbMain.ClientSize.Height - size.Height) / 2;
                generate_RightBottom();
                rounding();
            }
            
            private void generate_RightBottom()
            {
                this.Right = this.Left + this.size.Width;
                this.Bottom = this.Top + this.size.Height;
            }
            private void rounding()
            {
                size.Width = takeTenPercent(size.Width);
                size.Height = takeTenPercent(size.Height);
            }
            private int takeTenPercent(int value)
            {
                if (value % 10 > 0)
                    return Convert.ToInt32(Math.Round((double)value / 10) * 10);
                return value;
            }
            //get size of image after zoom in picturebox
            private static Size getZoomedImage(PictureBox pictureBox1)
            {
                float x = pictureBox1.ClientSize.Width; // Ширина клиентской области
                float y = pictureBox1.ClientSize.Height; // Высота клиентской области

                float z1 = pictureBox1.Image.Width; //Ширина загруженного изображения
                float z2 = pictureBox1.Image.Height; //Высота загруженного изображения

                float q;  // Коэффициент
                float q1; //Отмасштабированная ширина
                float q2; //Отмасштабированная высота

                if (z1 > x | z2 > y)
                {
                    if (z1 > z2)  // z1>x
                    {
                        q = z1 / x;//коофіцієнт = восота зобр/ висота блоку

                        q1 = z1 / q;
                        q2 = z2 / q;
                        if (q2 > y)
                        {
                            q = z2 / y;
                            q1 = z1 / q;
                            q2 = z2 / q;
                            return new Size((int)q1, (int)q2);
                        }
                        else
                        {
                            return new Size((int)q1, (int)q2);
                        }
                    }
                    if (z2 > z1)  // z2>y
                    {
                        q = z2 / y;
                        q1 = z1 / q;
                        q2 = z2 / q;
                        if (q1 > x)
                        {
                            q = z1 / x;
                            q1 = z1 / q;
                            q2 = z2 / q;
                            return new Size((int)q1, (int)q2);
                        }
                        else
                        {
                            return new Size((int)q1, (int)q2);
                        }
                    }
                }
                return new Size((int)z1, (int)z2);
            }

        }

        class MyCell
        {
            public Size size;

            public MyCell(MyImage image, int cellCountRows, int cellCountColumns)
            {
                this.size = new Size(Convert.ToInt32(image.size.Width / cellCountColumns), Convert.ToInt32(image.size.Height / cellCountRows));
            }
        }

        class MyCurrentCellPosition
        {
            MyImage image;
            public int x;
            public int y;

            public MyCell cell;

            public MyCurrentCellPosition(MyImage image, MyCell cell)
            {
                this.x = image.Left;
                this.y = image.Top;
                this.image = image;
                this.cell = cell;
            }

            public void NewRow()
            {
                this.y += cell.size.Height;
                this.x = image.Left;
            }

            public void NewCell()
            {
                this.x += cell.size.Width;
            }
        }


...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692119
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нащет скорости обработки ошибся.
Если использовать pbMain.Controls.AddRange(cells), обработка ускоряется раза в полтора.


предыдущий вариант(с класами): 2756 микросекунд
используя AddRange : 1110 микросекунд

но это всеравно много..

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
public static void CreateSections(PictureBox pbMain, IDictionary<string, string> dic, int cellCountRows = 20, int cellCountColumns =20 )
{
	MyImage image = new MyImage(pbMain);
	MyCell cell = new MyCell(image, cellCountRows, cellCountColumns);
	MyCurrentCellPosition curr = new MyCurrentCellPosition(image, cell);
	
	Cell[] cells = new Cell[401];
	for (int y = 1; y <= cellCountRows; y++)
	{
		for (int x = 1; x <= cellCountColumns; x++)
		{
			int number = x * y;
			cells[number] = new Cell(number, curr.y, curr.x, cell.size, dic["id"], ConnStr);
			curr.NewCell();
		}
		curr.NewRow();
	}
	pbMain.SuspendLayout();
	pbMain.Controls.AddRange(cells);
	pbMain.ResumeLayout();
}




Дело в том, что во время AddRange(как и в предыдущей поэлементной загрузке), изображение загружается кубиками.
Это при условиях:
pbMain.Visible=false;
pbMain.SuspendLayout();
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692210
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko,

контролы то зачем нужны? клик ловить и текстовое сообщение показывать?
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692764
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,
Так до меня было. Поэтому, я изменяю по-этапно.
Думаю, lblText, вообще можно убрать, заменив простой переменной.

Это конструкто класа Cell:
Код: 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.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
        public Cell(int number, int Top, int Left, Size size, string dic_id, string ConnStr)
        {
            InitializeComponent();
            this.Name = "VisComponent" + number.ToString();
            this.Top = Top;
            this.Left = Left;
            this.lblText.Text = number.ToString();
            this.Size = size;

            this.lblText.Size = this.Size;
            this.pnMain.Size = this.Size;

            
            this.pnMain.Click += delegate(object o, EventArgs e)
            {

                using (SqlConnection con = new SqlConnection(ConnStr))
                {
                    this.lblText.Visible = true;
                    this.lblText.ForeColor = Color.Red;
                    this.lblText.BackColor = Color.Red;

                    con.Open();
                    string sql = " insert into tbl_Transaction(AssmID, Position, LastUpdate) " +
                                    " values(@AssmID, @Position, GETDATE()) ";
                    using (SqlCommand com = new SqlCommand(sql, con))
                    {
                        com.Parameters.Add("@AssmID", dic_id);
                        com.Parameters.Add("@Position", this.lblText.Text);
                        com.ExecuteNonQuery();
                    }
                }

                System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
                timer.Interval = 1000;
                timer.Tick += (source, u) => { this.lblText.Visible = false; timer.Stop(); };
                timer.Start();
            };
        }

...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692797
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
К стати, выяснилось, что в два раза быстрее оно работает, потомучто размещает в два раза меньше компонентов.
Даже незнаю куда они с масива деваются.(картинка выше)
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692807
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko,

я правильно понимаю, что по клику нужно сделать запись в базу на секунду нарисовать красный прямоугольник?
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692824
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ИзопропилSNenko,

я правильно понимаю, что по клику нужно сделать запись в базу на секунду нарисовать красный прямоугольник?
Именно так.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692827
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SNenkoК стати, выяснилось, что в два раза быстрее оно работает, потомучто размещает в два раза меньше компонентов.
Даже незнаю куда они с масива деваются.(картинка выше)
Тут моя ошибка я умножал: х*у.
надо было просто number++;
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692838
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Получается, что поэлементно и массивом оно заносит почти одинаково(разница на 100 микросекунд).
Я думаю, что много времени занимает поэлементная прорисовка.
Незнаю как ее отключить..
Во всяком случае, код стал более читабелен(для меня)

Приступлю к варианту с кликами на bictureBox. Тоесть, без масива, а с прорисовкой конкретного килика.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692932
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenkoПриступлю к варианту с кликами на bictureBox. Тоесть, без масива, а с прорисовкой конкретного килика.
правильный путь.

потребуется одна панель, на ней рисуется картинка и закрашиваются прямоугольники
и никаких лишних контролов
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38693245
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,

Перфоманс Аналайзер вам в помощь, на нём увидите где программа больше всего тормозит и там уже будите думать, как это решить.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38693459
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman MejtesИзопропил,

Перфоманс Аналайзер вам в помощь, на нём увидите где программа больше всего тормозит и там уже будите думать, как это решить.


Господа теоретики, не нужна мне помощь, я читать код умею.
Да и задачка не у меня.

В данном случае - тормоза на беспощадном и бессмысленном создании сотен windows контролов.
Несчастный обработчик клика мыши - не нуждается в оптимизации. Если только с эстетической точки зрения
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38693510
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Roman MejtesИзопропил,

Перфоманс Аналайзер вам в помощь, на нём увидите где программа больше всего тормозит и там уже будите думать, как это решить.
я пользуюсь своим класом.
Но спасибо Вам за совет!

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
public class SW : Stopwatch
{
	public SW()
	{
		this.Start();
	}

	public void write(string text)
	{
		if (this.IsRunning)
		{
			this.Stop();
			Console.WriteLine("{0} (час: {1})", text, this.ElapsedMilliseconds);
			//--Console.WriteLine("{0} (час: {1})", text, this.Elapsed);
			this.Reset();
		}
		else
			Console.WriteLine("{0}", text);
		this.Start();
	}
}
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38696699
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кому интересно:
Работает "моментально"!)))

Создал клас MySensorPictureBox , унаследованый от PictureBox.
Добавил в него метод определения и прорисовки ячейки в заданхых рамках, при нажатии мышки.

Код не опримизирован(не было времени) и есть не используемые методы/класы.

использование класа:
Код: c#
1.
pbMain.ActivateSensorMatrix(addDic, Helper.ConnStr, Matrix.Height, Matrix.Width);




Код MySensorPictureBox:
Код: 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.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace TouchUpDataCollection.Classes
{
    public class MySensorPictureBox : PictureBox
    {
        private MyImage myImage;
        private MyCell cell;
        private MyCurrentCell curr_cell;
        private IDictionary<string, string> addDic;
        private Size matrixSize;
        private Size matrixAllCellsSize {
                        get { return new Size((this.cell.Size.Width*this.matrixSize.Width) + this.myImage.Left,
                                                (this.cell.Size.Height * (this.matrixSize.Height)) + this.myImage.Top);
                                              //(this.cell.Size.Height*(this.matrixSize.Height - 1)) + this.myImage.Top);
                        }
        }
        public string ConnStr = "";
        public bool isSensorMatrixActive { get { return (this.cell == null) ? false : true; } }
        public bool isMatrix(int x, int y)
        {
            if (this.myImage.Left > x) return false;
            if (this.matrixAllCellsSize.Width < x) return false;
            if (myImage.Top > y) return false;
            if (this.matrixAllCellsSize.Height < y) return false;
            return true;
            /*
            return ((this.myImage.Left <= x)
                 && (x <= (this.matrixAllCellsSize.Width))
                 && (myImage.Top <= y)
                 && (y <= (this.matrixAllCellsSize.Height)));
            */
        }
        //private int WidthAllCells()

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (this.isSensorMatrixActive)
                if (this.isMatrix(e.X, e.Y))
                    this.showBar(new Point(e.X, e.Y));
        }

        private Size getSizeCell()
        {
            return new Size(Convert.ToInt32(this.myImage.size.Width / this.matrixSize.Width), Convert.ToInt32(this.myImage.size.Height / this.matrixSize.Height));
        }

        public void ActivateSensorMatrix(IDictionary<string, string> addDic, string ConnStr, int cellCountRows, int cellCountColumns)
        {
            if (base.Image == null)
            {
                MessageBox.Show("Image is empty!",Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            this.myImage = new MyImage(this);
            //--this.myImage = new MyImage(this.ClientSize, this.Image.Size);
            this.addDic = addDic;
            this.ConnStr = ConnStr;
            this.matrixSize.Height = cellCountRows;
            this.matrixSize.Width = cellCountColumns;
            this.cell = new MyCell(getSizeCell());
            //this.matrixAllCellsSize = new 
        }

        public void showBar(Point clickPosition)
        {
            this.curr_cell = new MyCurrentCell(this.cell.Size, clickPosition, this.matrixSize, new Size(this.myImage.Left, this.myImage.Top) );

            if (this.curr_cell.Number > (this.matrixSize.Width * this.matrixSize.Height))
                return;
            MessageBox.Show("x=" + clickPosition.X + "; y=" + clickPosition.Y + "; number = " + this.curr_cell.Number);

            Cell r = new Cell(curr_cell.Location, curr_cell.Size);
            this.Controls.Add(r);
            Cell.Activate(r);
            Cell.SaveClickToDB(this.ConnStr, addDic["id"], this.curr_cell.Number);
            
            System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
            timer.Interval = 1000;
            timer.Tick += (source, u) => { Cell.UnActivate(r); timer.Stop(); this.Controls.Remove(r); r.Dispose(); };
            timer.Start();
            
            
            //Cell.processingpnMain_Event_OnClick(r, curr_cell.Number, this.ConnStr, this.addDic["id"]);
        }

        private void InitializeComponent()
        {
            ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
            this.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
            this.ResumeLayout(false);

        }
    }
    
    class MyImage
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
        public Size size;
        //!!!з розміром зображення фігня твориться
        public MyImage(PictureBox pb)
        {
            this.size = getZoomedImage(pb);
            this.Left = (pb.ClientSize.Width - size.Width) / 2;
            this.Top = (pb.ClientSize.Height - size.Height) / 2;
            generate_RightBottom();
            rounding();
        }
        /*
        public MyImage(Size ClientSize, Size sizeImage)
        {
            this.size = getZoomedImage(ClientSize, sizeImage);
            this.Left = (ClientSize.Width - size.Width) / 2;
            this.Top = (ClientSize.Height - size.Height) / 2;
            generate_RightBottom();
            rounding();
        }*/


        private void generate_RightBottom()
        {
            this.Right = this.Left + this.size.Width;
            this.Bottom = this.Top + this.size.Height;
        }
        private void rounding()
        {
            size.Width = takeTenPercent(size.Width);
            size.Height = takeTenPercent(size.Height);
        }
        private int takeTenPercent(int value)
        {
            if (value % 10 > 0)
                return Convert.ToInt32(Math.Round((double)value / 10) * 10);
            return value;
        }
        //get size of image after zoom in picturebox
        private static Size getZoomedImage(PictureBox p)
        {
            return getZoomedImage(p.ClientSize, p.Image.Size);
        }

        private static Size getZoomedImage(Size clientSize, Size imageSize)
        {
            float x = clientSize.Width; // Ширина клиентской области
            float y = clientSize.Height; // Высота клиентской области

            float z1 = imageSize.Width; //Ширина загруженного изображения
            float z2 = imageSize.Height; //Высота загруженного изображения

            float q;  // Коэффициент
            float q1; //Отмасштабированная ширина
            float q2; //Отмасштабированная высота

            if (z1 > x | z2 > y)
            {
                if (z1 > z2)  // z1>x
                {
                    q = z1 / x;//коофіцієнт = восота зобр/ висота блоку

                    q1 = z1 / q;
                    q2 = z2 / q;
                    if (q2 > y)
                    {
                        q = z2 / y;
                        q1 = z1 / q;
                        q2 = z2 / q;
                        return new Size((int)q1, (int)q2);
                    }
                    else
                    {
                        return new Size((int)q1, (int)q2);
                    }
                }
                if (z2 > z1)  // z2>y
                {
                    q = z2 / y;
                    q1 = z1 / q;
                    q2 = z2 / q;
                    if (q1 > x)
                    {
                        q = z1 / x;
                        q1 = z1 / q;
                        q2 = z2 / q;
                        return new Size((int)q1, (int)q2);
                    }
                    else
                    {
                        return new Size((int)q1, (int)q2);
                    }
                }
            }
            return new Size((int)z1, (int)z2);
        }

    }

    class MyCell//:Padding
    {
        public Size Size;


        public MyCell(MyImage image, int cellCountRows, int cellCountColumns)
        {
            this.Size = new Size(Convert.ToInt32(image.size.Width / cellCountColumns), Convert.ToInt32(image.size.Height / cellCountRows));
        }

        public MyCell(Size size)
        {
            this.Size = size;
        }

    }

    class MyCurrentCellPosition
    {
        MyImage image;
        public int x;
        public int y;
        public Int32 number=1;

        public MyCell cell;

        public MyCurrentCellPosition(MyImage image, MyCell cell)
        {
            this.x = image.Left;
            this.y = image.Top;
            this.image = image;
            this.cell = cell;
            //--this.number = 1;
        }

        public void NewCell()
        {
            this.number++;
            this.x += cell.Size.Width;
        }

        public void NewRow()
        {
            this.y += cell.Size.Height;
            this.x = image.Left;
        }
        /*
        public static Size LocationCellByNumber(int number)
        {
            return new Size(number, number);
        }
        */
    }


    class MyCurrentCell : MyCell
    {
        //public Point CoordinateXY;
        public Padding Pannding { get { return new Padding(this.Left, this.Top, this.Right, this.Bottom); } set { this.Left = value.Left; this.Right = value.Right; this.Top = value.Top; this.Bottom = value.Bottom; } }
        public Point Location;
        //public Size Size;
        public int Right { get { return (this.Location.X + this.Size.Width); } set { this.Size.Width = value - this.Location.X; } }
        public int Bottom { get { return (this.Location.Y + this.Size.Height); } set { this.Size.Height = value - this.Location.Y; } }
        public int Left { get { return this.Location.X; } set { this.Location.X = value; } }
        public int Top { get { return this.Location.Y; } set { this.Location.Y = value; } }

        private Size matrixSize;
        private Size LeftTopImagePosition;

        public int Number = 0;
        public MyCurrentCell(Size size, Point clickPosition, Size matrixSize, Size LeftTopImagePosition): base(size)
        {
            this.Size = size;
            this.LeftTopImagePosition = LeftTopImagePosition;
            this.matrixSize = matrixSize;
            this.Location = getCoordinate(clickPosition);
            this.Number = getNumber(LeftTopImagePosition, clickPosition);
            
        }
        //визначає номер комірки
        private int getNumber(Size locationComponent, Point coordinate)
        {
            int res = 1;
            int count_x = ((coordinate.X - locationComponent.Width) / this.Size.Width)+1;
            int count_y = ((coordinate.Y - locationComponent.Height) / this.Size.Height);

            //if(count_y > 0) count_y = (count_y * this.matrixSize.Width) - 1) else count_y 0;
            count_y = (count_y > 0) ? (count_y * this.matrixSize.Width) : 0;

            //з підрахунком тоже странне
            res = count_y + count_x;
            if (res < 1) res = 1;

            return res;
        }

        //визначає координати блока
        private Point getCoordinate(Point mice)
        {
            int count_x, count_y, cell_left, cell_top;

            //count_x = (mice.X / this.Size.Width);
            count_x = getCountCellsByX(mice.X);
            cell_left = this.LeftTopImagePosition.Width+((count_x) * this.Size.Width);

            //count_y = (mice.Y / this.Size.Height);
            count_y = getCountCellsByY(mice.Y);
            cell_top = this.LeftTopImagePosition.Height + ((count_y) * this.Size.Height);

            return new Point(cell_left, cell_top);
        }

        private int getCountCellsByX(int x)
        {
            int w = this.LeftTopImagePosition.Width;
            return ((x - w) / this.Size.Width);
        }

        private int getCountCellsByY(int y)
        {
            int h = this.LeftTopImagePosition.Height;
            return ((y -h) / this.Size.Height);
        }

        public static Size LocationCellByNumber(Point positionImage, Size sizeCell, Size matrixSize, int number)
        {
            number--;
            int x, y, y_count_max = matrixSize.Height;
            y = (number / y_count_max);
            x = (number - (y * y_count_max));
            
            y = positionImage.Y+(y*sizeCell.Height);
            x = positionImage.X + (x*sizeCell.Width);

            return new Size(x, y);
        }
    }


}



Спасибо!
Вы мне очень помогли!
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38696976
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko,

ошибочки есть с таймером.

Ссылку на него сохранять нужно ( у Рихтера прикол описан с досрочной смертью таймера)
ну и при уничтожении контрола все таймеры прибить нужно, а не то эти зомби могут обратиться к несуществующим объектам

Вероятность описанного невелика, но всё же
...
Рейтинг: 0 / 0
27 сообщений из 27, показаны все 2 страниц
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как ускорить работу кода?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]