Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
171 / 120 / 14
Регистрация: 17.06.2013
Сообщений: 386
1

Не меняется значение label в цикле

24.03.2014, 14:43. Показов 2781. Ответов 11
Метки нет (Все метки)

Код вроде такого

C#
1
2
3
4
5
private void button1_Click(object sender, RoutedEventArgs e) {
    for(int i; i<m; i++) {
        label.Content = i;
    }
}
Проблема - значение label изменяется только после выхода из цикла.
0

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

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.03.2014, 14:43
Ответы с готовыми решениями:

Не могу понять где в цикле меняется значение переменной
Доброго времени суток! Сижу и не могу понять где и почему меняется значение digits Код: void...

Не меняется текст Label
Вот такой код: Gar GGG = new Gar(); string query = &quot;SELECT count(*)&quot; + &quot;FROM table1&quot;;...

Не меняется положение label по Y
смысл: при наведении на картинку за мышкой следует лейбл который отображает какое то описание,...

Label.text не меняется
Вообщем столкнулся с такой проблемой, динамически создается Label и ему присваивается значение...

11
987 / 885 / 354
Регистрация: 24.03.2014
Сообщений: 2,381
Записей в блоге: 2
24.03.2014, 14:46 2
Скажем так, оно изменяется, но только интерфейс в это время подвешен циклом. Если дать ему передышку, то он справится и покажет значение, естественно, что цикл будет дольше идти.
0
171 / 120 / 14
Регистрация: 17.06.2013
Сообщений: 386
24.03.2014, 15:07  [ТС] 3
TheSpawn, запихнул Thread.Sleep(1000), результат тот же. Да и не выход это.

Добавлено через 12 минут
C#
1
2
3
4
5
6
7
8
label.Content = "Парсинг";
{
     // блаблабла полминуты работает
}
label.Content = "Выгрузка данных";
{
     // блаблабла еще полминуты
}
Даже в этом случае значение label изменится только после того как будут завершены обе операции. Что за бред, и как с этим бороться?
0
481 / 437 / 122
Регистрация: 05.01.2010
Сообщений: 1,836
24.03.2014, 15:08 4
задавать содержимое лейблов в другом потоке?
0
987 / 885 / 354
Регистрация: 24.03.2014
Сообщений: 2,381
Записей в блоге: 2
24.03.2014, 15:12 5
Цитата Сообщение от 5665tm Посмотреть сообщение
Что за бред, и как с этим бороться?
Цитата Сообщение от valera_21 Посмотреть сообщение
задавать содержимое лейблов в другом потоке?
Это не бред, так уж "многозадачность" устроена.

Sleep Вы и правда задали для текущего же потока, так что и цикл заставил интерфейс уснуть и метод Sleep(). Следуйте совету valera_21.
0
171 / 120 / 14
Регистрация: 17.06.2013
Сообщений: 386
24.03.2014, 15:15  [ТС] 6
valera_21,

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private void SetLabelParse()
{
    label.Content = "Парсинг"
}
 
 
....
 
 
Thread th = new Thread(SetLabelParse);
th.Start;
{
     // блаблабла полминуты работает
}
label.Content = "Выгрузка данных";
{
     // блаблабла еще полминуты
}

Исключение: Вызывающий поток не может получить доступ к данному объекту, так как владельцем этого объекта является другой поток.
0
72 / 72 / 20
Регистрация: 11.01.2014
Сообщений: 252
Записей в блоге: 2
24.03.2014, 15:20 7
интересно, а что вы такое хотите сделать хитрое? может весь код покажите?
0
987 / 885 / 354
Регистрация: 24.03.2014
Сообщений: 2,381
Записей в блоге: 2
24.03.2014, 15:26 8
Цитата Сообщение от 5665tm Посмотреть сообщение
Исключение: Вызывающий поток не может получить доступ к данному объекту, так как владельцем этого объекта является другой поток.
Вызов метода в том же потоке, в каком был создан элемент управления.

А вообще да, интересно узнать, а что же это такое будет.
0
171 / 120 / 14
Регистрация: 17.06.2013
Сообщений: 386
24.03.2014, 16:49  [ТС] 9
golandy, TheSpawn, да ничего интересного, это просто парсер из екселя в ексель. Показать не могу, на работе все осталось. Записей очень много, поэтому надо бы отображать прогресс, да вот столкнулся с тем что в цикле (одна итерация - одна строка) не обновляется визуально ни label.Info, ни progressBar.Value

Пробовал через BackGroundWorker, но от него пришлось отказаться по ряду причин.
0
29 / 29 / 10
Регистрация: 17.08.2010
Сообщений: 95
24.03.2014, 18:03 10
>А вообще да, интересно узнать, а что же это такое будет
Да скорее всего, человек хочет отобразить прогресс.
Нет, просто так это не получится.
Если это silverlight, можно останавливать процесс, обновлять DOM и продолжать этот процесс.
По-другому можно делить процесс на чанки и после каждого чанка (на языке родных осин куска) делать таймаут, чтоб позволить GUI обновиться
0
Эксперт .NET
4341 / 2003 / 387
Регистрация: 27.03.2010
Сообщений: 5,460
Записей в блоге: 1
24.03.2014, 19:55 11
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
        private void SetParserState(ProgramState state)
        {
            if (!Dispatcher.CheckAccess()) //Если вызывающий поток не связан с объектом Dispatcher (тоесть другой поток), то вызываем этот же метод через BeginInvoke
                Dispatcher.BeginInvoke((Action<ProgramState>)SetParserState, state);
            else
            {
                switch (state)
                {
                    case ProgramState.Default:
                        parseButton.IsEnabled = true;
                        infoTextBlock.Text = "Информация";
                        stateTextBlock.Text = string.Empty;
                        progressBar.Value = progressBar.Minimum;
                        progressBar.IsIndeterminate = false;
                        break;
                    case ProgramState.ParsingStarted:
                        parseButton.IsEnabled = false;
                        stateTextBlock.Text = "Выполняется парcинг";
                        progressBar.IsIndeterminate = true;
                        break;
                    case ProgramState.ParsingEnded:
                        parseButton.IsEnabled = true;
                        stateTextBlock.Text = "Парсинг закончен";
                        progressBar.Value = progressBar.Maximum;
                        progressBar.IsIndeterminate = false;
                        break;
                    case ProgramState.Export:
                        stateTextBlock.Text = "Выполняется экспорт данных";
                        progressBar.IsIndeterminate = true;
                        break;
                }
            }
        }
Добавлено через 39 секунд
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        private void ParseButton_Click(object sender, RoutedEventArgs e)
        {
            if (!_backgroundWorker.IsBusy)
            {
                if (!Directory.Exists(Global.Settings.RootDirectoryForParsing))
                {
                    MessageBox.Show(this, "Папка не существует. Выберите папку, в которой находятся документы для парсинга.",
                        Title, MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    OpenSettingsDialog(true);
                    return;
                }
                SetParserState(ProgramState.ParsingStarted);
                string excelDocPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "exportData.xlsx");
                string rootDirectoryForParsing = Global.Settings.RootDirectoryForParsing;
                _backgroundWorker.RunWorkerAsync(new Tuple<string, string>(excelDocPath, rootDirectoryForParsing));
            }
        }
Добавлено через 42 секунды
C#
1
2
3
4
5
6
7
8
9
10
11
        /// <summary>
        /// Установить текст на текстовое поле отображающее информацию о парсинге. Можно вызывать не из UI потока.
        /// </summary>
        /// <param name="text">Передаваемый текст</param>
        private void SetTextToInformationTextBlock(string text)
        {
            if (infoTextBlock.CheckAccess()) //проверяем метод вызван из потока создавшего TextBlock или нет
                infoTextBlock.Text = text;
            else
                Dispatcher.BeginInvoke((Action<string>)SetTextToInformationTextBlock, text);
        }
Добавлено через 1 минуту
Короче, как-то так
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
        private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var arguments = (Tuple<string, string>)e.Argument;
            string excelDocPath = arguments.Item1;
            string rootDirectoryForParsing = arguments.Item2;
 
            List<string> files = new List<string>(5000);
 
            FileHelper.GetAllFiles(rootDirectoryForParsing, "*.htm", files);
 
            DocumentParserFactory docParserFactory = new DocumentParserFactory(); //Создаём фабрику парсеров
            docParserFactory.RegisterParser(new ChemicalCompositionOfMeltingVer1Parser());
            docParserFactory.RegisterParser(new ChemicalCompositionOfMeltingVer2Parser());
            docParserFactory.RegisterParser(new PassportOfMeltingParser());
 
            ExcelExporter exporter = new ExcelExporter(excelDocPath);
 
            Parser parser = new Parser(docParserFactory, exporter);
            //Тут мы подписываемся на событие DocumentParsed, 
            //после парсинга каждого документа вызывается ниже определённый анонимный метод 
            parser.DocumentParsed += (s, args) => 
                SetTextToInformationTextBlock(string.Format("Прогресс: выполнено {0} из {1}. Ошибок парсинга {2}",
                args.ParsedQuantity, files.Count, args.ErrorsQuantity));
 
            parser.ExportStarted += (s, args) => SetParserState(ProgramState.Export);
 
            Tuple<List<IDocument>, List<string>> tupleParsingResult = parser.Parse(files);
 
            e.Result = tupleParsingResult;
        }
Добавлено через 23 секунды
Это всё с одного класса методы

Добавлено через 5 минут
Это я писал, когда ещё о MVVM только просто слышал, что это круто, но боялся попробовать в деле

Добавлено через 11 минут
Цитата Сообщение от 5665tm Посмотреть сообщение
Пробовал через BackGroundWorker, но от него пришлось отказаться по ряду причин.
Можно услышать несколько?

Добавлено через 44 секунды
В общем, как не получать исключение смотри в одном из методов, что я выложил, самый короткий который
1
710 / 677 / 126
Регистрация: 30.03.2012
Сообщений: 1,124
24.03.2014, 20:00 12
это может показаться на первый взгляд (или даже на второй) сложным, но откройте для себя Reactive extensions
они великолепны

ваша задача на Rx решается следующим образом:
XML
1
2
3
4
5
6
7
8
9
10
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        Name="Window">
    <Grid>
        
        <Label Content="{Binding ElementName=Window, Path=CurrentRow}"/>
    </Grid>
</Window>
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        public class ExcelParser
        {
            private readonly Subject<int> _subject=new Subject<int>(); 
            // Subject - позволяет как создавать новые уведомления так и подписываться на них
            public IObservable<int> ParsedRows { get { return _subject.AsObservable(); } }
            //возвращаем только ту часть Subject на которую можно подписаться
 
            public void ParseExcel()
            {
                for (var i = 0; i < 100; i++)
                {
                    Thread.Sleep(100); // тут ваш код который парсит строку из экселя
                    _subject.OnNext(i); // создаем уведомление о том что мы обработали очередную строку
                }
                _subject.OnCompleted(); // создаем уведомление о том что обработка завершена
            }
        }
окно:
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
public partial class MainWindow : Window
    {
        public static readonly DependencyProperty CurrentRowProperty =
            DependencyProperty.Register("CurrentRow", typeof (int), typeof (MainWindow), new PropertyMetadata(default(int)));
 
        public int CurrentRow
        {
            get { return (int) GetValue(CurrentRowProperty); }
            set { SetValue(CurrentRowProperty, value); }
        }
 
        private ExcelParser parser;
        private readonly IDisposable _parserSubscription;
 
        public MainWindow()
        {
            InitializeComponent();
            parser = new ExcelParser(); // наш парсер
            _parserSubscription = Disposable.Empty; 
            // подписка на события парсера. вызов Dispose - прекратить получать уведомления
            parser.ParsedRows.ObserveOn(new DispatcherScheduler(Dispatcher)) 
            //сообщаем что обрабатывать уведомления будем в потоке диспатчера (интерфейсном потоке)
                .Subscribe(
            //подписываемся на уведомления
                    x => CurrentRow = x,
            // записываем в CurrentRow (к которому привязан Content метки) номер новой обработанной строки
            // этот метод вызывается при вызове OnNext на источнике уведомлений
                    _ => _parserSubscription.Dispose(),
            // если произошла ошибка (OnError на источнике) - отписываемся
                    () => _parserSubscription.Dispose());
            // если закончили (OnCompleted на источнике) - тоже отписываемся
            Task.Factory.StartNew(() => parser.ParseExcel());
            // запускаем парсер экселя в новом потоке
        }
установить Rx можно через Nuget например вот этой командой: https://www.nuget.org/packages/Rx-WPF/
хороший мануал можно найти здесь: http://www.introtorx.com/
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.03.2014, 20:00

Почему не меняется label?
Не выводится в label using System; using System.Collections.Generic; using...

Не меняется свойство Caption у Label
procedure TForm1.FormClick(Sender: TObject); var i: integer; s: string; begin i := 5; s...

Почему не меняется текст в label. Qt C++
Нужно при нажатии кнопки &quot;startButton&quot; выводить текст &quot;startButton pressed&quot;void...

Почему не меняется цвет в Label
пишу код Label1-&gt;Color=clRed; Label1-&gt;Font-&gt;Color=clRed; при запуске программы цвет остается...

Почему не меняется текст в label?
Form4 f4 = new Form4(); b = f4.label3.Text; int qek; qek =...

Не меняется отображение Label на форме внутри цикла
Доброго времени! using System; using System.Collections.Generic; using System.ComponentModel;...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.