Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/18: Рейтинг темы: голосов - 18, средняя оценка - 4.67
119 / 119 / 25
Регистрация: 03.03.2010
Сообщений: 436

Процесс загрузки Crystal report отобразить в Progressbar

05.03.2013, 12:54. Показов 3329. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет. Никогда не работал с потоками до этого. Необходимо грузить отчет Crystal report по нажатию на кнопку. Но при первом запуске он зависает секунд на 5-7( грузятся всякие библиотеки). Как сделать чтобы прогресс бар грузился пока отчет висит,чтобы была имитация работы. Нашел код так заполнять прогрессбар
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
public partial class Form1 : Form
    {
        BackgroundWorker bw;
        public Form1()
        {
            InitializeComponent();
            progressBar1.Maximum = 100;
            progressBar1.Step = 1;
 
            bw = new BackgroundWorker();
            bw.WorkerReportsProgress = true;
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        }
 
        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            //...
            //делаем что-то
            //...
            for (int i = 0; i < 101; i++)
            {
                ((BackgroundWorker)sender).ReportProgress(i);
                Thread.Sleep(30);
             //   MessageBox.Show("a");
            }
        }
 
        void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }
 
        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Text = "Работа окончена";
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Text = "Работа выполняется";
            bw.RunWorkerAsync();
        }
    }
Но вот куда мне пихнуть вызов otchet.ShowDialog(); не понимаю.. Подскажете?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.03.2013, 12:54
Ответы с готовыми решениями:

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

Отобразить в ProgressBar процесс чтения большого файла
Доброго времени суток! Случилось мне такое задание: Написать приложение, которое отображает количество текста, прочитанного из файла...

Процесс открытия файла Word отобразить в ProgressBar
Есть форма, нажимаю кнопку -&gt; запускается процесс открытия ворд-файла. Так как происходит всё оооочень медленно, решил вставить...

9
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
05.03.2013, 13:01
Цитата Сообщение от jonni Посмотреть сообщение
Но вот куда мне пихнуть вызов otchet.ShowDialog(); не понимаю.. Подскажете?
В bw_RunWorkerCompleted, если работа не была отменена и не произошла ошибка во время генерирования отчета.
1
119 / 119 / 25
Регистрация: 03.03.2010
Сообщений: 436
05.03.2013, 13:03  [ТС]
kolorotur, благодарю.а генерацию отчета куда вставить?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
05.03.2013, 13:04
Цитата Сообщение от jonni Посмотреть сообщение
а генерацию отчета куда вставить?
Если генерация занимает много времени, то разумеется в bw_DoWork.
А результат этой генерации уже передавать в новую форму для отображения.
0
119 / 119 / 25
Регистрация: 03.03.2010
Сообщений: 436
05.03.2013, 13:41  [ТС]
Что-то не получается...
Переписал метод
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            //...
            //делаем что-то
            //...
                       for (int i = 0; i < 101; i++)
            {
 
                ((BackgroundWorker)sender).ReportProgress(i);
                Thread.Sleep(50);
                f16 f = new f16();
                f.Owner = this;
                 f.load_report_settings(ps.dataset_crystal, "df", "350000 Краснодар", "df", 10, "Иванов", " ");
               
            }
 
        }
load_report_settings-передает данные для отчета. А теперь вызываю его

C#
1
2
3
4
5
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Text = "Работа окончена";
          f.ShowDialog();
        }
Но прогрессбар не двигается, а сразу грузится пустой отчет, т.к. метод load_report_settings тоже не запускался
0
 Аватар для kodv
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
05.03.2013, 15:03
jonni, не совсем понял. Вы RunWorkerCompleted вызываете самостоятельно? Тогда понятно, почему у вас отчет пустой, в него данные еще не загрузились, они только начали грузиться в потоке. Это событие, которое должно возникнуть, когда у вас закончится выполнение метода bw_DoWork.
Нужно понимать, для чего используются потоки. Вы хотите, чтобы у вас одновременно происходила загрузка отчета и обновление прогресс бара. Чтобы эти действия происходили параллельно, они должны выполняться в разных потоках. В вашем случае у вас данные в отчет будут грузится 100 раз, и после каждого раза будет двигаться прогресс бар.
Цитата Сообщение от jonni Посмотреть сообщение
чтобы была имитация работы
Для того, чтобы пользователь понял, что идет загрузка данных и нужно подождать, можно обойтись и меньшей кровью. Например, просто изменить курсор мышки на часики, пока у вас будет грузится отчет.
1
 Аватар для Игрок_со_Смерть
37 / 37 / 6
Регистрация: 06.01.2013
Сообщений: 195
05.03.2013, 15:08
Как вариант можно использовать делегат для доступа к прогресс бару чтобы грузить в него состояние=)

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private delegate void SetProgressHandler(int value, int maxValue); //Создаем объект типа делегат 
 
        private void ProgressValue(int value, int maxValue)//Создаем метод который будет вызываться делегатом
        {
            progressBar.Maximum = maxValue;
            progressBar.Value = value;
        }
 
        public void valueProgress(int value, int maxValue) // Метод добавления строки из другого потока
        {
            if (progressBar.InvokeRequired) // Проверяем в этом ли потоке находится созданный объект 
            {
                progressBar.Invoke(new SetProgressHandler(this.ProgressValue), value, maxValue); //Создаем экземпляр объекта типа делегат, вызываем в нем нужный метод, и передаем переменные
            }
            else // Если метод вызывается в том же потоке что и объект то
            {
                progressBar.Value = value; // вызываем метод
            }
        }
Вызываем так
C#
1
valueProgress(2, 100)
1
119 / 119 / 25
Регистрация: 03.03.2010
Сообщений: 436
05.03.2013, 16:39  [ТС]
Цитата Сообщение от kodv Посмотреть сообщение
Чтобы эти действия происходили параллельно, они должны выполняться в разных потоках.
Подскажите пожалуйста, как это сделать?

Цитата Сообщение от kodv Посмотреть сообщение
просто изменить курсор мышки на часики, пока у вас будет грузится отчет.
Можно, но хотелось бы научиться работать и с потоками. Не особо понимаю как работать с ними.
Хотелось бы так грубо говоря так:
C#
1
2
3
4
5
6
7
potok1
{
}
potok2
{
}
potoki.start();// и они сами параллельно выполняются.
Но как они на самом деле работают?
Можно пример не с отчетом, а допустим с проверкой данных в БД при авторизации,один поток проверяет, другой изменяет прогресс бар или текст на label?
0
 Аватар для Игрок_со_Смерть
37 / 37 / 6
Регистрация: 06.01.2013
Сообщений: 195
05.03.2013, 17:28
вот для примера исходник вроде сложного ничего нет=)
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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
 
 
 
 
namespace ScanPort
{
    public partial class Form1 : Form
    {
        Thread t;
        int startPort;
        int endPort;
 
        public Form1()
        {
            InitializeComponent();
            progressBar.Maximum = 100;
            progressBar.Minimum = 0;
            startPort = int.Parse(textStartPort.Text);
            endPort = int.Parse(textEndPort.Text);
 
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            if (startPort > endPort)
            {
                listLog.Items.Add("Указан не верный диапазон  сканируемых портов. Диапазон должен быть от 0 до 65535");
            }
            else 
            {
                t = new Thread(new ThreadStart(scanPort));
                t.Start();
            }
            
        }
 
        void scanPort()
        {
            IPAddress ipAddress = IPAddress.Parse(textIP.Text);
             
            string item = null;
            int j = 0;
 
            for (int i = startPort; i <  endPort; i++)
            {
                int maxValue = endPort - startPort;
                
                addItem(maxValue.ToString());
                j++;
                valueProgress(j, maxValue);
                try
                {
                    IPEndPoint endPoint = new IPEndPoint(ipAddress, i);
                    Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    client.SendTimeout = 0;
                    client.Connect(endPoint);
 
                    item = String.Format("Порт: {0} | Доступен", i);
 
                    addItem(item);
                }
                catch (SocketException errors)
                {
                    item = String.Format("Порт: {0} | Ошибка {1} : {2}", i, errors.ErrorCode, errors.Message);
                    addItem(item);
                }
            }
            t.Abort();
        }
 
        private delegate void SetListBoxItem(string name);//Создаём объект типа делигат
 
        private void LoadItemsListCallBack(string item) //Создаём метод который будет вызываться делигатом
        {
            listLog.Items.Add(item); // добовляем строки в ListLog
        }
 
        public void addItem(string item) // Метод добавления строки из другого потока
        {
            if (listLog.InvokeRequired) // Проверяем в этом ли потоке нахождится созданый обьект 
            {
                SetListBoxItem lstBoxItem = new SetListBoxItem(this.LoadItemsListCallBack); // Создаём экземпляр обьекта типа делигат
                this.Invoke(lstBoxItem, new object[] { item }); // Передаём ему значение
            }
            else // Если метод вызывается в том же потоке что и обьект то
            {
                listLog.Items.Add(item); // добовляем строку
            }
        }
 
        private delegate void SetProgressHandler(int value, int maxValue); //Создаём обьект типа делигат 
 
        private void ProgressValue(int value, int maxValue)//Создаём метод который будет вызываться делигатом
        {
            progressBar.Maximum = maxValue;
            progressBar.Value = value;
        }
 
        public void valueProgress(int value, int maxValue) // Метод добавления строки из другого потока
        {
            if (progressBar.InvokeRequired) // Проверяем в этом ли потоке нахождится созданый обьект 
            {
                progressBar.Invoke(new SetProgressHandler(this.ProgressValue), value, maxValue); //Создаём экземпляр обьекта типа делигат, вызываем в нем нужный метод, и передаём переменные
            }
            else // Если метод вызывается в том же потоке что и обьект то
            {
                progressBar.Value = value; // вызываем метод
            }
        }
 
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            
            t.Abort();
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            t.Abort();
        }
    }
}
0
 Аватар для kodv
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
06.03.2013, 07:13
jonni, Чтобы вам было проще разобраться с BackgroundWorker, модифицировал ваш код и расставил комментарии
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
public partial class Form1 : Form
{
    public MainForm()
    {
        InitializeComponent();
    }
 
    private void button1_Click(object sender, EventArgs e)
    {
        // Создаем фоновй поток, который будет грузить данные
        BackgroundWorker dataLoadBackgroundWorker = new BackgroundWorker();
        // Цепляем обработчик на событие DoWork
        dataLoadBackgroundWorker.DoWork += new DoWorkEventHandler(dataLoadBackgroundWorker_DoWork);
        // Запускаем работу потока, передаем потоку кнопку, по которой он запустился
        dataLoadBackgroundWorker.RunWorkerAsync(sender);
    }
 
    void dataLoadBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        // Дизаблим переданную потоку кнопку через Invoke, чтобы пользователь опять на нее нажать
        ((Control)e.Argument).Invoke(new buttonDelegate(buttonEnabledOnOff), e.Argument);
        // Создаем фоновый поток, в котором будет имитация бурной деятельности через прогресс бар
        BackgroundWorker progressBarBackgroundWorker = new BackgroundWorker();
        // Задаем свойство, которое позволит этот поток в будущем остановить
        progressBarBackgroundWorker.WorkerSupportsCancellation = true;
        // Цепляем обработчик на событие DoWork
        progressBarBackgroundWorker.DoWork += new DoWorkEventHandler(progressBarBackgroundWorker_DoWork);
        // Запускаем поток и передаем в него прогресс бар
        progressBarBackgroundWorker.RunWorkerAsync(progressBar1);
        // Имитация загрузки отчета, усыпляем поток на 10 секунд
        System.Threading.Thread.Sleep(10000);
        // будем считать, что отчет загрузился, поэтому нам не нужно больше заполнять прогресс бар. Остановим этот поток
        progressBarBackgroundWorker.CancelAsync();
        // Енаблим переданную потоку кнопку через Invoke, чтобы пользователь в дальнейшем мог на нее нажать
        ((Control)e.Argument).Invoke(new buttonDelegate(buttonEnabledOnOff), e.Argument);
    }
 
    void progressBarBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        // Здесь заполняется прогресс бар
        // Пока выполнение потока не отменится, заполняем полосу прогрессбара используя Invoke. Между итерациями делаем задержку в 30 мс
        for (; !((BackgroundWorker)sender).CancellationPending; ((Control)e.Argument).Invoke(new progressBarDelegate(progressBarInc), e.Argument))
            System.Threading.Thread.Sleep(30);
    }
 
    // Делегат для метода, изменяющего полосу прогресс бара
    private delegate void progressBarDelegate(ProgressBar progressBar);
 
    private void progressBarInc(ProgressBar progressBar)
    {
        // Заполняем полосу прогресс бара. Если достигли максимума, переходим в начало полосы
        progressBar.Value = (progressBar.Value + 1) % progressBar.Maximum;
    }
 
    // Делегат для метода, изменящего доступность кнопки
    private delegate void buttonDelegate(Button button);
 
    private void buttonEnabledOnOff(Button button)
    {
        // Изменяем доступность кнопки
        button.Enabled = !button.Enabled;
    }
}
Тем не менее, повторюсь, в данной ситуации лучше либо менять указатель мыши, либо, если так хочется прогресс бар, то делать так
C#
1
progressBar1.Style = ProgressBarStyle.Marquee;
. Заполнение обычного прогресс бара будет выглядеть некрасиво. Расчитать точное время выполнения загрузки отчета вряд ли получится. Узнать, на какой стадии находится загрукза отчета, тоже не получится. Поэтому не получится сделать так, чтобы за время выполнения загрузки прогресс бар заполнился с 0% до 100%.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
06.03.2013, 07:13
Помогаю со студенческими работами здесь

Как можно процесс архивации отобразить в ProgressBar
Здравствуйте такой вопрос как можно процесс архивации отобразит в ProgressBar-е? вот код архива. FastZip fZip = new...

Отобразить в toolStripProgressBar процесс загрузки файла в richTextBox
Есть кнопка с помощью которой открывается rtf файл в richTextBox'e, также есть элемент toolStripProgressBar, как сделать так, чтобы про...

crystal report
как динамически выводить картинку? В crystal report XI developer edition можно указать ссылку на объект в Picture и всё работает, как...

Crystal Report в VS2010
Купила диск Visual Studio 2010 Ultimate. Вроде установила, приложение заработало и база подключилась. Создаю новый элемент в проекте - их...

Crystal Report и DataSet
Здравствуйте. Мне нужно распечатать одну из таблиц DataSet с помощью Crystal Report. Как мне это сделать? База данных при этом не...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru