Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614

ProgressBar для загрузки/выгрузки БД

03.02.2017, 15:27. Показов 5486. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток.
При загрузки формы происходит выгрузка базы данных в DataSet:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void Form1_Load(object sender, EventArgs e)
{
      try
      {
             this.historyTableAdapter.Fill(CommonData.localDBDataSet.History);
             this.measureTableAdapter.Fill(CommonData.localDBDataSet.Measure);
             this.typeDataTableAdapter.Fill(CommonData.localDBDataSet.TypeData);
             this.dataTableAdapter.Fill(CommonData.localDBDataSet.Data);
             this.typeHistoryTableAdapter.Fill(CommonData.localDBDataSet.TypeHistory);
       }
       catch (System.Data.SqlClient.SqlException)
       {
              MessageBox.Show("Ошибка подключения к базе данных", "Ошибка");
 
              Application.Exit();
        }
}
А при закрытии формы происходит обновление базы данных:
C#
1
2
3
4
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
        this.tableAdapterManager.UpdateAll(CommonData.localDBDataSet);
}
Так как база обширная, происходит задержка программы во время этих двух обработчиков.

Мне нужно сделать ProgressBar для этого, чтобы пользователь видел степень загрузки/выгрузки базы данных.
Как мне это реализовать? Подскажите пожалуйста

Добавлено через 7 часов 39 минут
Никто не знает?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.02.2017, 15:27
Ответы с готовыми решениями:

Скачивание файла WebClient с отображением процентов загрузки файла, progressBar, скоростью загрузки файла
Приветствую! Нужна Ваша помощь... Имеется такой кодик, слепленный из готовых примеров System.Net.WebClient webClient =...

Прогресс загрузки файлов в ProgressBar
Здравствуйте, есть вот такой вот код: using System; using System.Collections.Generic; using System.Windows.Forms; using System.Net;...

Отображение статус загрузки в progressbar и label
Как отследить статус загрузки в прогресс баре и в лейбле? Пример на скриншоте снизу. Спасибо. Код для кнопки. private void...

19
 Аватар для sysrepos
82 / 76 / 30
Регистрация: 08.08.2013
Сообщений: 455
Записей в блоге: 1
03.02.2017, 15:37
Пример с прогрессбаром. Но возможно в вашем случае для прогрессбарам надо использовать стиль
C#
1
progressBar1.Style = ProgressBarStyle.Marquee;
Вложения
Тип файла: 7z 1-прогресбар.7z (29.4 Кб, 32 просмотров)
0
 Аватар для sysrepos
82 / 76 / 30
Регистрация: 08.08.2013
Сообщений: 455
Записей в блоге: 1
03.02.2017, 15:39
в любом случае для использования прогрессбара нужно уметь работать с многопоточностью.
про многопоточность можно посмотреть тут https://www.youtube.com/watch?v=D9qcKV4j75U&t=5s
0
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
03.02.2017, 17:23  [ТС]
sysrepos, Я так и понял, что нужна многопоточность. Принцип работы я знаю, работал с ней на c++. На C# многопоточность не использовал, но думаю, разберусь.
0
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
03.02.2017, 18:30
Вот вариант с загрузкой одной таблицы. Работает только с SELECT *, сортируя по первому столбцу. Отображается прогресс загрузки, а после завершения отображает таблицу.
Кликните здесь для просмотра всего текста
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
void Main()
{
    Application.Run(new MainForm());
}
 
class MainForm: Form
{
    public MainForm()
    {
        WindowState = FormWindowState.Maximized;
        Load += MainForm_Load;
    }
    
    private async void MainForm_Load(object sender, EventArgs args)
    {
        var connectionString = @"Data Source=.\MYSERVER; Initial Catalog=AdventureWorks2014; Integrated Security = true";
        var dataTable = new DataTable();
        var dataAdapter = new SqlDataAdapter("SELECT * FROM [Person].[Person]", connectionString);
 
        var pb = new ProgressBar
        {
            Parent = this,
            Minimum = 0,
            Maximum = 100,
            Value = 0,
        };
 
        var dgv = new DataGridView
        {
            Parent = this,
            Top = 100,
            AutoSize = true
        };
 
        var progress = new Progress<int>();
        progress.ProgressChanged += (s, value) => 
        {
            pb.Value = value;
            if (value == 100)
            {
                dgv.DataSource = dataTable;
            }
        };
 
        var task = dataAdapter.FillAsync(dataTable, 1000, progress);
 
        await task;
    }
}
 
static class SqlDataAdapterExtensions
{
    public static Task FillAsync(this SqlDataAdapter adapter, DataTable dataTable, int rowsPerBlock, IProgress<int> progress = null)
    {
        return Task.Run(() =>
        {
            progress?.Report(0);
            
            string selectText = adapter.SelectCommand.CommandText;
            
            int total = GetCount(adapter);
            int steps = total / rowsPerBlock + (total % rowsPerBlock != 0 ? 1 : 0);
            for (int start = 0, step = 0; start < total; start += rowsPerBlock, step++)
            {
                adapter.SelectCommand = new SqlCommand($"{selectText} order by (1) offset {start} rows fetch next {rowsPerBlock} rows only", adapter.SelectCommand.Connection);
                adapter.Fill(dataTable);
                
                double percentage = Math.Min((step + 1) / (double)steps * 100, 99);
                progress?.Report((int)percentage);
            }
            
            progress?.Report(100);
        });
    }
    
    private static int GetCount(SqlDataAdapter adapter)
    {
        string selectText = adapter.SelectCommand.CommandText.Replace("*", "COUNT(*)");
 
        int count;
    
        using (var connection = new SqlConnection(adapter.SelectCommand.Connection.ConnectionString))
        {
            connection.Open();
            var countCommand = new SqlCommand(selectText, connection);
            count = (int)countCommand.ExecuteScalar();
        }
        
        return count;
    }
}
1
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
03.02.2017, 19:06  [ТС]
TopLayer, Прошу прощения, код в принципе понятен, но я не очень разбираюсь в синтаксисе C#'па. Вы не могли бы уточнить, что значит символ ? вот тут:
C#
1
progress?.Report(0);
и символ $ в передачи строки как параметра вот здесь:
C#
1
$"{selectText} order by (1) offset {start} rows fetch next {rowsPerBlock} rows only"
0
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
03.02.2017, 19:14
Bretbas, это новые фишки C# 6.0
1) то же самое что и
C#
1
if (progress != null) progress.Report(0);
2) то же самое что и
C#
1
string.Format("{0} order by (1) offset {1} rows fetch next {2} rows only", selectText, start, rowsPerBlock);
1
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
03.02.2017, 19:21  [ТС]
TopLayer, Понял Спасибо.

Я не могу никак Ваш код подсоединить к своему проекту, так как объект адаптер у меня создается конструктором, я его не инициализирую вот так:
C#
1
var dataAdapter = new SqlDataAdapter("SELECT * FROM [Person].[Person]", connectionString);
он где-то внутри сам по себе создается.

Из-за этого возникают проблемы. К примеру когда выполняется вот эта строчка:
C#
1
string selectText = adapter.SelectCommand.CommandText;
у меня выпадает исключение
An unhandled exception of type 'System.Reflection.TargetInvocationExcep tion' occurred in mscorlib.dll
Additional information: Адресат вызова создал исключение.
0
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
03.02.2017, 19:28
Bretbas, я не понимаю как в этой строчке может быть такое исключение. Тут нужна "помощь зала".
0
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
03.02.2017, 19:37  [ТС]
TopLayer,
Цитата Сообщение от TopLayer Посмотреть сообщение
я не понимаю как в этой строчке может быть такое исключение. Тут нужна "помощь зала".
Я тоже не очень понимаю, так как не знаю как работает конструктор C#'па для создания Адаптера и всяких его приколюшек...
Но возможно подвох в том, что он в этом конструкторе создается без параметра строки(запроса), а метод Fill, который является стандартным у него, уже имеет в себе запрос.
А так как в твоем коде:
C#
1
string selectText = adapter.SelectCommand.CommandText;
идет запрос на получение строки запроса адаптера, который по идее должен был инициализироваться в его конструкторе, то у меня возможно выдает из-за этого ошибку, так как C# конструктор адаптера его не передает в начале.

Че-то я как-то запутанно написал

Добавлено через 4 минуты
TopLayer, ладно хрен с ним, с этим ProgressBar'ом. Лучше подскажи как мне сделать тогда просто "крутящий кружочек", когда выполняется вот этот код:
C#
1
2
3
4
5
             this.historyTableAdapter.Fill(CommonData.localDBDataSet.History);
             this.measureTableAdapter.Fill(CommonData.localDBDataSet.Measure);
             this.typeDataTableAdapter.Fill(CommonData.localDBDataSet.TypeData);
             this.dataTableAdapter.Fill(CommonData.localDBDataSet.Data);
             this.typeHistoryTableAdapter.Fill(CommonData.localDBDataSet.TypeHistory);
Думаю нужно поток запускать дополнительный, в нем запускать форму, которая имеет вид крутящегося кружочка, а в главном потоке уже выполнять все Fill'ы?

Если честно, меня попросили написать программу на C#, вот я и пишу, но не очень хочется вдаваться в подробности этого языка, так как мне он не очень симпатичен...C++ - вот мощь
0
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
03.02.2017, 20:14
Bretbas, как такой вариант?
Кликните здесь для просмотра всего текста
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
class MainForm: Form
{
    public MainForm()
    {
        Text = "MainForm";
        Load += MainForm_Load;
    }
 
    private async void MainForm_Load(object sender, EventArgs args)
    {
        var cts = new CancellationTokenSource();
        new WaitingForm(cts.Token).Show(this);
        Enabled = false;
        
        await Task.Run(() =>
        {
            // time consuming operation
            Thread.Sleep(5000);
            cts.Cancel();
            Invoke((Action)delegate { Enabled = true; });
        });
    }
}
 
class WaitingForm : Form
{
    CancellationToken _ct;
    
    public WaitingForm(CancellationToken ct)
    {
        _ct = ct;
        StartPosition = FormStartPosition.CenterScreen;
        Size = new Size(300, 30);
        FormBorderStyle = FormBorderStyle.None;
        Load += WaitingForm_Load;
    }
 
    private void WaitingForm_Load(object sender, EventArgs args)
    {
        var pb = new ProgressBar { Parent = this, Style = ProgressBarStyle.Marquee, Dock = DockStyle.Fill };
 
        new System.Windows.Forms.Timer { Enabled = true, Interval = 1000 }.Tick += (_, __) =>
        {
            if (_ct.IsCancellationRequested) Close();
        };
    }
}
 
void Main()
{
    Application.Run(new MainForm());
}
1
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
03.02.2017, 20:19  [ТС]
TopLayer, Я не очень понял этот пример, а чего собственно ждет форма WaitingForm?
0
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
03.02.2017, 20:24
Цитата Сообщение от Bretbas Посмотреть сообщение
а чего собственно ждет форма WaitingForm?
18ю строку
0
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
03.02.2017, 20:26  [ТС]
, Тоесть чтобы выполнить Fill'ы для всех таблиц, мне нужно поместить их в обработчик Run объекта Task?
Да, и что такое CancellationTokenSource?
0
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
03.02.2017, 20:35
Цитата Сообщение от Bretbas Посмотреть сообщение
мне нужно поместить их в обработчик Run объекта Task?
Ну да, правда это не обработчик.
Цитата Сообщение от Bretbas Посмотреть сообщение
Да, и что такое CancellationTokenSource?
Источник токенов отмены
Короче если пишешь cts.Cancel(), то все токены, полученные путём cts.Token, буду иметь свойство IsCancellationRequested == true. И всё это безопасно в отношении потоков.

Добавлено через 3 минуты
Bretbas, кстати вместо таймера лучше вот так сделать
C#
1
_ct.Register(() => Invoke((Action)delegate { Close(); }));
2
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
03.02.2017, 21:01  [ТС]
TopLayer,
Цитата Сообщение от TopLayer Посмотреть сообщение
Короче если пишешь cts.Cancel(), то все токены, полученные путём cts.Token, буду иметь свойство IsCancellationRequested == true. И всё это безопасно в отношении потоков.

Ах это грязное событийно-управляемое программирование
Ща попробую

Добавлено через 17 минут
TopLayer, Итак, попробовал. Возникло две проблемы:
1. Ты в своем коде делаешь главное окно недоступным Enabled = false;. Так работает. Я хочу сделать окно невидимым. Заменяю гребанный Enabled на Visible. У меня не работает. Окно не становится невидимым. Как-будто ничего не происходит

2. Вот мой код:
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
        private async void MainForm_Load(object sender, EventArgs e)
        {
            var cts = new CancellationTokenSource();
            new Form1(cts.Token).Show(this);
            this.Enabled = false;
 
            await Task.Run(() =>
            {
                // Загружаем базу данных
                try
                {
                    this.historyTableAdapter.Fill(CommonData.localDBDataSet.History);
                    this.measureTableAdapter.Fill(CommonData.localDBDataSet.Measure);
                    this.typeDataTableAdapter.Fill(CommonData.localDBDataSet.TypeData);
                    this.dataTableAdapter.Fill(CommonData.localDBDataSet.Data);
                    this.typeHistoryTableAdapter.Fill(CommonData.localDBDataSet.TypeHistory);
                }
                catch (System.Data.SqlClient.SqlException)
                {
                    MessageBox.Show("Ошибка подключения к базе данных", "Ошибка");
 
                    // Закрываем приложение
                    Application.Exit();
                }
 
                // Источник данных для таблицы Measure
                this.measureBindingSource.DataMember = "Measure";
                this.measureBindingSource.DataSource = CommonData.localDBDataSet;
 
                // Источник данных для таблицы TypeData
                this.typeDataBindingSource.DataMember = "TypeData";
                this.typeDataBindingSource.DataSource = CommonData.localDBDataSet;
 
                // Источник данных для таблицы Data
                this.dataBindingSource.DataMember = "FK_Data_ToTypeData";
                this.dataBindingSource.DataSource = this.typeDataBindingSource;
                this.dataBindingSource.Sort = "name";
 
                // Столбец id_measure привязываем к таблице Measure
                this.id_measure.DataPropertyName = "id_measure";
                this.id_measure.DisplayMember = "measure";
                this.id_measure.ValueMember = "id";
 
                cts.Cancel();
 
                Invoke((Action)delegate 
                {
                    this.Enabled = true; 
                });
            });
        }
На вот этой строке this.typeDataBindingSource.DataMember = "TypeData"; происходит исключение:
An unhandled exception of type 'System.Reflection.TargetInvocationExcep tion' occurred in mscorlib.dll
Additional information: Адресат вызова создал исключение.

хотя без потоков, этот код работал. Бред вообще. Я уже замудохался

Добавлено через 6 минут
Второй вопрос отпал, просто инициализацию источников данных переместил вот в этот блок:
C#
1
2
3
4
                Invoke((Action)delegate 
                {
                    this.Enabled = true; 
                });
все заработало
0
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
03.02.2017, 21:02
Лучший ответ Сообщение было отмечено Bretbas как решение

Решение

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
        private async void MainForm_Load(object sender, EventArgs e)
        {
            var cts = new CancellationTokenSource();
            new Form1(cts.Token).Show(this);
                Opacity = 0;
        ShowInTaskbar = false;
        Enabled = false;
 
            await Task.Run(() =>
            {
                // Загружаем базу данных
                try
                {
                    this.historyTableAdapter.Fill(CommonData.localDBDataSet.History);
                    this.measureTableAdapter.Fill(CommonData.localDBDataSet.Measure);
                    this.typeDataTableAdapter.Fill(CommonData.localDBDataSet.TypeData);
                    this.dataTableAdapter.Fill(CommonData.localDBDataSet.Data);
                    this.typeHistoryTableAdapter.Fill(CommonData.localDBDataSet.TypeHistory);
                }
                catch (System.Data.SqlClient.SqlException)
                {
                    MessageBox.Show("Ошибка подключения к базе данных", "Ошибка");
 
                    // Закрываем приложение
                    Application.Exit();
                }
            });
 
                // Источник данных для таблицы Measure
                this.measureBindingSource.DataMember = "Measure";
                this.measureBindingSource.DataSource = CommonData.localDBDataSet;
 
                // Источник данных для таблицы TypeData
                this.typeDataBindingSource.DataMember = "TypeData";
                this.typeDataBindingSource.DataSource = CommonData.localDBDataSet;
 
                // Источник данных для таблицы Data
                this.dataBindingSource.DataMember = "FK_Data_ToTypeData";
                this.dataBindingSource.DataSource = this.typeDataBindingSource;
                this.dataBindingSource.Sort = "name";
 
                // Столбец id_measure привязываем к таблице Measure
                this.id_measure.DataPropertyName = "id_measure";
                this.id_measure.DisplayMember = "measure";
                this.id_measure.ValueMember = "id";
 
                cts.Cancel();
                Enabled = true;
        ShowInTaskbar = true;
        Opacity = 100;
        }
1
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
03.02.2017, 21:28  [ТС]
TopLayer, Спасибо! Очень выручил. Вроде все работает

Добавлено через 13 минут
TopLayerКстати, вопрос не в тему. Если я создаю форму вот так:
C#
1
new Form1(cts.Token).Show(this);
не будет утечек памяти? Ведь я ее не освобождаю? Или как в C# это происходит?
0
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
03.02.2017, 22:36
Цитата Сообщение от Bretbas Посмотреть сообщение
не будет утечек памяти
не будет. Это вам не с++ где одни объекты забывают удалить, другие же удаляют по несколько раз
Здесь же автоматический сборщик мусора периодически (по наступлению некоторых событий) просматривает все ссылочные переменные (корни), находит все достижимые из них объекты и помечает их как 'нельзящасудалять'. Все остальные объекты удаляются.
1
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
04.02.2017, 07:36  [ТС]
TopLayer, Понял Я не знал, что C# имеет сборщик мусора
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.02.2017, 07:36
Помогаю со студенческими работами здесь

Отображение процесса загрузки странички WebBrowser-а в ProgressBar-е
Доброго всем дня! Появилась такая проблема: на форме разместил listview, webbrowser, progressbar. В listview отображаются ссылки на...

Процесс загрузки Crystal report отобразить в Progressbar
Всем привет. Никогда не работал с потоками до этого. Необходимо грузить отчет Crystal report по нажатию на кнопку. Но при первом запуске он...

Выводить текст в Label во время загрузки ProgressBar
Всем привет! Подскажите, как мне сделать мою задумку по progressbar? Хочу чтобы во время загрузки ProgressBar. У меня в Label выводился...

Загрузка progressBar во время загрузки картинки в pictureBox из пути
Здравствуйте. :read: Можно сделать так, чтобы progressBar появлялся на экране и не зависал, после того, как мы нажали на кнопку, у...

Отобразить процесс загрузки (создания) объекта/куска_кода в ProgressBar
Итак, здравствуйте, у меня есть объект ProgressBar и кусок кода: // ... var excelApp = new...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

Новые блоги и статьи
sshd restrictions, ssh access limitations
jigi33 26.03.2025
sshd restrictions | ssh access limitations рестрикции доступа на сервер sshd статья: https:/ / www. golinuxcloud. com/ restrict-allow-ssh-certain-users-groups-rhel
Компиляция C++ с Clang API
NullReferenced 24.03.2025
Компиляторы обычно воспринимаются как черные ящики, которые превращают исходный код в исполняемые файлы. Мы запускаем компилятор командой в терминале, и вуаля — получаем бинарник. Но что если нужно. . .
Многопоточное программировани­е в C#: Класс Thread
UnmanagedCoder 24.03.2025
Когда запускается приложение на компьютере, операционная система создаёт для него процесс - виртуальное адресное пространство. В C# этот процесс изначально получает один поток выполнения — главный. . .
SwiftUI Data Flow: Передача данных между представлениями
mobDevWorks 23.03.2025
При первом знакомстве со SwiftUI кажется, что фреймворк предлагает избыточное количество механизмов для передачи данных: @State, @Binding, @StateObject, @ObservedObject, @EnvironmentObject и другие. . . .
Моки в Java: Сравниваем Mockito, EasyMock, JMockit
Javaican 23.03.2025
Как протестировать класс, который зависит от других сложных компонентов, таких как базы данных, веб-сервисы или другие классы, с которыми и так непросто работать в тестовом окружении? Для этого и. . .
Архитектурные паттерны микросервисов: ТОП-10 шаблонов
ArchitectMsa 22.03.2025
Популярность микросервисной архитектуры объясняется множеством важных преимуществ. К примеру, она позволяет командам разработчиков работать независимо друг от друга, используя различные технологии и. . .
Оптимизация рендеринга в Unity: Сортировка миллиона спрайтов
GameUnited 22.03.2025
Помните, когда наличие сотни спрайтов в игре приводило к существенному падению производительности? Время таких ограничений уходит в прошлое. Сегодня геймдев сталкивается с задачами совершенно иного. . .
Образование и практика
Igor3D 21.03.2025
Добрый день А вот каково качество/ эффективность ВУЗовского образования? Аналитическая геометрия изучается в первом семестре и считается довольно легким курсом, что вполне справедливо. Ну хорошо,. . .
Lazarus. Таблица с объединением ячеек.
Massaraksh7 21.03.2025
Понадобилась представление на экране таблицы с объединёнными ячейками. И не одной, а штук триста, и все разные. На Delphi я использовал для этих целей TStringGrid, и то, кривовато получалось. А в. . .
Async/await в Swift: Асинхронное программировани­е в iOS
mobDevWorks 20.03.2025
Асинхронное программирование долго было одной из самых сложных задач для разработчиков iOS. В течение многих лет мы сражались с замыканиями, диспетчеризацией очередей и обратными вызовами, чтобы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru