Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
2 / 2 / 1
Регистрация: 12.01.2017
Сообщений: 36

Обновление listView по таймеру

07.09.2017, 23:50. Показов 1969. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Вопрос вроде бы очень частый, но ничего годного пока не нашел и не придумал.

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

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
 public partial class StatusForm : Form
    {
        public StatusForm()
        {
            //System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();
            btClose.Enabled=false;
            //Add();
            progressBar1.Maximum = 100;
        }
 
        private void AddToView()
        {
            int count = listView.Items.Count;
            {
                if (count < MyLog.MyMsg.LogList.Count)
                {
                    for (int i = count; i < MyLog.MyMsg.LogList.Count; i++)
                    {
                        AddToView(MyMsg.LogList[i]);
                    }
                }
            }
        }
 
        private void AddToView(MyMsg MyMsg)
        {
            ListViewItem lvi = new ListViewItem();
 
            lvi.SubItems.Add(MyMsg.dateTime.ToString());
            lvi.SubItems.Add(MyMsg.title);
            lvi.SubItems.Add(MyMsg.val);
 
            listView.Items.Add(lvi);
        }
 
        public void work()
        {
            timer1.Start();
        }
        public void ShowBtClose()
        {
            BeginInvoke(new DelegateShowBtCLose(ShowClose));
        }
 
        public void AddNew()
        {
            BeginInvoke(new DelegateAdd(work));
        }
 
        public void SetPb(int pc)
        {
            BeginInvoke(new DelegateSetPc(SetPbPc), pc);
        }
 
        private delegate void DelegateShowBtCLose();
        private delegate void DelegateAdd();
        private delegate void DelegateSetPc(int pc);
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            AddToView();
        }
 
        private void btClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
 
        private void ShowClose()
        {
            btClose.Enabled = true;
            MessageBox.Show("Готово");
        }
 
        private void SetPbPc(int pc)
        {
            progressBar1.Value = pc;
        }
    }
Все достаточно просто. Запускается таймер, в нем запускается метод который проверяет нужно ли добавить новые записи в listView. Для включения кнопки "Закрыть" и для задания процентов в статус бар сделал делегаты. Пожалуй, это не очень хорошая идея, и логичней было бы установить модификатор public на эти контролы, и изменять их свойства с другой формы. Но! поскольку эта форма запускается в отдельном потоке, то при таком подходе выходит ошибка:Недопустимая операция в нескольких потоках: попытка доступа к элементу управления <название контрола> не из того потока, в котором он был создан. При использовании делегатов такая ошибка не возникает.

Далее, на основной форме есть кнопка. (убрал многопоточность дабы строчек меньше и понятнее было...)
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
private void button4_Click(object sender, EventArgs e)
        {
            var msg = new MyMsg(title: "msg1", val: 0);
            msg = new MyMsg(title: "msg2", val: 0);
 
            StatusForm statusForm = new StatusForm();
            Thread wThread = new Thread(() => statusForm.ShowDialog());
            wThread.Start();
 
            statusForm.btClose.Enabled = true;
            Thread.Sleep(200); // Если строчку убрать возникает ошибка:
            //Невозможно вызвать Invoke или BeginInvoke для элемента управления
            //до завершения создания дескриптора окна
 
            statusForm.AddNew();
            statusForm.SetPb(3);
 
            Thread.Sleep(2000);
            //statusForm.progressBar1.Value = 33; // Недопустимая операция в нескольких потоках:
            //попытка доступа к элементу управления 'progressBar1' не из того потока, в котором он был создан.
            msg = new MyMsg(title: "msg3", val: 0);
            Thread.Sleep(2000);
            msg = new MyMsg(title: "msg4", val: 0);
            Thread.Sleep(2000);
            msg = new MyMsg(title: "msg5", val: 0);
            Thread.Sleep(2000);
            statusForm.ShowBtClose();
        }
Если я убираю строчку Thread.Sleep(200); то все перестает работать, я так понимаю, что пытаюсь получить доступ к элементам, которые еще не были созданы.
Как дождаться создания формы?
Да и вообще, как это все сделать красиво и по человечески ?

Огромное спасибо, очень надеюсь на вашу помощь
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.09.2017, 23:50
Ответы с готовыми решениями:

Обновление списка файлов и папок в ListView, желательно не по таймеру
Делаю простой файловый менеджер (аля проводник), в принципе уже почти всё сделал, но понимаю что абсолютно не правильно сделал обновление...

Обновление текста по таймеру
Что нужно: Раз в секунду идёт пересчёт данных внутри приложения и эти обновлённые данные выводятся на экран. Что сделано: ...

Обновление страницы в WebBrowser по таймеру
Как реализовать обновление webBrowser1.Refresh(); в соответствии с таймером, к примеру - страница обновляется каждые 5 секунд?? Если можно,...

4
1 / 1 / 0
Регистрация: 27.08.2016
Сообщений: 6
08.09.2017, 02:43
Я мало разбираюсь и может даже и не понял задания.
Но я бы дождался создания формы используя bool, while и backgroundworker.
1
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
08.09.2017, 08:20
Цитата Сообщение от Alex_rt Посмотреть сообщение
Да и вообще, как это все сделать красиво и по человечески ?
Зачем сувать создаваемую форму в отдельный поток это что за изврат?

Добавлено через 12 минут
Кликни по проекту правой клавишей мыши , добавь к проэкту новую форму прорисуй ее в графическом дизайнере.

В главной форме по нажатию кнопки вызывай ее и назначь что она дочерняя.

Потом переходи к коду 2 формы (form2.cs) и как она загрузится вызывай потоки , складывай это все в коллекцию какую нибудь, при закрытии 2 формы обновишь первую
1
2 / 2 / 1
Регистрация: 12.01.2017
Сообщений: 36
08.09.2017, 09:14  [ТС]
Пробовал до этого сделать через backgroundworker, но я сильно переборщил с делегатами, и все время сыпались ошибки.
Нашел пример, удалил лишнее, нужное добавил, и все заработало как надо...

Цитата Сообщение от EVG-1980 Посмотреть сообщение
Потом переходи к коду 2 формы (form2.cs) и как она загрузится вызывай потоки , складывай это все в коллекцию какую нибудь, при закрытии 2 формы обновишь первую
Вот казалось бы, все просто, логично и понятно. Но почему я до этого раньше не додумался? гм.. не знаю...

всем спасибо, я разобрался)
если кому пригодиться ссылка на пример
http://perschluter.com/show-pr... s-c-sharp/
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
08.09.2017, 09:23
Цитата Сообщение от Alex_rt Посмотреть сообщение
Вот казалось бы, все просто, логично и понятно. Но почему я до этого раньше не додумался? гм.. не знаю...
И потоки впринципе не нужны если ты используешь свойство родитель у форм то получишь доступ из 2 формы к контролам первой и можешь сразу в них писать
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.09.2017, 09:23
Помогаю со студенческими работами здесь

Таймер: Как сделать обновление по таймеру?
String myArr = new string; myArr = &quot;массив с первыми значениями&quot;; myArr = &quot;массив с первыми значениями&quot;; ...

Сделать обновление формы каждые 5 минут по таймеру
подскажите, как сделать обновление формы каждые 5 минут по таймеру

Обновление окна по таймеру: форма все равно зависает
Всем привет! Делаю вот так void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { ...

Динамическое обновление ListView
Здравствуйте! Передо мной стоит такая задача: Имеются данные, которые меняются динамически. Имеется ListView, в который...

Обновление списка процессов в Listview
Здравствуйте. Нужно выводить список процессов с обовлением каждые 0,5 секунд. Обновление должно быть без мерцания. Вот код: private void...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru