Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.68/37: Рейтинг темы: голосов - 37, средняя оценка - 4.68
0 / 0 / 0
Регистрация: 12.12.2021
Сообщений: 205

ProgressBar в MVVM

02.04.2022, 20:36. Показов 9543. Ответов 86
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Помогите, пожалуйста, нужно сделать индикатор выполнения (ProgressBar) какого-либо процесса в MVVM в Авалонии. Правильно, ли я делаю?

XML
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
<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:Test_progress.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="Test_progress.Views.MainWindow"
        Icon="/Assets/avalonia-logo.ico"
        Title="Test_progress">
 
    <Design.DataContext>
        <vm:MainWindowViewModel/>
    </Design.DataContext>
    <StackPanel>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
        </Grid>
        <ProgressBar Grid.Row="1" Height="20" Width="200" Name="progressBar" Margin="10" />
        <TextBlock Grid.Row="2" Name="MyTextBlock" HorizontalAlignment="Center" Margin="10"/>
        <Button Grid.Row="3" HorizontalAlignment="Center" Width="70" Content="Do_Work" Command="{Binding DoWork_button_click}" Margin="10" />
    </StackPanel>
</Window>

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
using Avalonia.Controls;
using Avalonia.Interactivity;
using System;
using System.ComponentModel;
using System.Threading;
 
namespace Test_progress.Views
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
           // progress = this.Find<ProgressBar>("progressBar");
        }
 
       private void DoWork_button_click(object sender, RoutedEventArgs e)
        {
            BackgroundWorker worker = new BackgroundWorker();
            worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
            worker.WorkerReportsProgress = true;
            worker.DoWork += Worker_DoWork;
            worker.ProgressChanged += Worker_ProgressChanged;
            worker.RunWorkerAsync();
 
        }
 
        private void Worker_ProgressChanged(object? sender, ProgressChangedEventArgs e)
        {
            progressBar.Value = e.ProgressPercentage;
            MyTextBlock.Text = (string)e.UserState;
        }
 
        private void Worker_DoWork(object? sender, DoWorkEventArgs e)
        {
            var worker = sender as BackgroundWorker;
            worker.ReportProgress(0, String.Format("Processing iteration 1"));
            for (int i=0; i<10; i++)
            {
                Thread.Sleep(1000);
                worker.ReportProgress((i+1)*10, String.Format("Processing iteration {0}", i+2));
            }
            worker.ReportProgress(100, "Done");
        }
 
        private void Worker_RunWorkerCompleted(object? sender, RunWorkerCompletedEventArgs e)
        {
            progressBar.Value = 0;
            MyTextBlock.Text = " ";
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using Avalonia.Controls;
using Avalonia.Interactivity;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Threading;
 
namespace Test_progress.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
       
    }
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.04.2022, 20:36
Ответы с готовыми решениями:

ProgressBar в MVVM
Здравствуйте. Пытаюсь реализовать простой пример на MVVM. Суть работы заключается в работе функции в которой циклически ghjbc class...

Рисую линию без MVVM все ОК. C MVVM произвольный старт
Добрый день всем. Рисую линию при помощи анимации. Все получилось -рисуется, стирается. Но у нас все задания с MVVM, чтобы ViewModel...

Консольный progressbar или progressbar в TMemo
Здравствуйте. Хочу спросить ради интереса как создать вот такой ProgressBar но с указанием своих сиволов в консоли и в...

86
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
15.04.2022, 14:04
Студворк — интернет-сервис помощи студентам
Sun1212, и так, я вижу, что Вы делаете через токен отмены, но в реализации, которую я показывал ранее, всё куда проще.

Я просто добавил поле isCanceled в модель:
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 static class FileManagerService
    {
        private static bool isCanceled;
 
        public static event FileCreatingProcessHandler FileCreated;
 
        public static void CreateFiles(int count)
        {
            isCanceled = false;
            var catalogPath = @"C:\Files\";
 
            // Если каталога Files не существует на диске C
            if (!Directory.Exists(catalogPath))
            {
                // тогда мы его создаём
                Directory.CreateDirectory(Path.GetDirectoryName(@"C:\Files\"));
            }
 
            for (int i = 0; i < count; i++)
            {
                if (isCanceled)
                    break;
 
                Thread.Sleep(300);
 
                // создаём пустой .txt файл
                var file = File.Create(@"C:\Files\" + i + ".txt");
                file.Close();
 
                // "говорим в микрофон" что произошло создание файла
                FileCreated?.Invoke(i, count);
            }
        }
 
        public static void CancelCreatingFiles()
        {
            isCanceled = true;
        }
    }
То есть если мы изменим на true, то цикл в методе CreateFiles остановится, а следовательно и метод завершится.
Также я заметил баг, ибо я не знал, что файл ещё нужно закрыть, после того, как его создаю. Поэтому добавил строку file.Close();.

Ну и просто в VM теперь создал команду:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    public class FileManagerViewModel : ReactiveObject
    {
        private int _progress;
        public int Progress { get => _progress; set => this.RaiseAndSetIfChanged(ref _progress, value); }
 
        public ReactiveCommand<Unit, Unit> CancelCommand => ReactiveCommand.Create(CancelExecute);
 
        private void CancelExecute()
        {
            FileManagerService.CancelCreatingFiles();
        }
 
        public FileManagerViewModel()
        {
            FileManagerService.FileCreated += OnModelFileCreated;
        }
 
        private void OnModelFileCreated(int fileIndex, int filesCount)
        {
            Progress = (int)((100 / (double)filesCount) * (fileIndex + 1)); // +1, потому что отсчёт начинается с нуля.
        }
    }
И на View добавил кнопку, которую подвязал к команде во ViewModel'е:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<Window x:Class="B.ProgressWindow" xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="B" Width="500" Height="200">
 
    <Grid Background="#1e1e1e">
        <StackPanel VerticalAlignment="Center" Margin="50">
            <ProgressBar Value="{Binding Progress}" Maximum="100"/>
            <TextBlock Text="{Binding Progress}" Foreground="White"/>
            
            <Button Height="60" HorizontalAlignment="Stretch"
                    Background="#7160e8" CornerRadius="10"
                    Command="{Binding CancelCommand}">
                <Button.Content>
                    <Label Content="Cancel" Foreground="White"
                           HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Button.Content>
            </Button>
        </StackPanel>
    </Grid>
    
</Window>



P.S.
Также нашёл ещё один баг в программе: если нажать на кнопку Start более чем один раз, то одновременно запустятся два одинаковых процесса, по сути.
Но по задаче не было такого условия, поэтому я это никак и не предусматривал.
Вложения
Тип файла: zip ProgressBarMVVMStudySolution.zip (9.6 Кб, 8 просмотров)
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
15.04.2022, 14:37
Цитата Сообщение от Sun1212 Посмотреть сообщение
CancelTokenSource.Cancel();
Предположу, что вы ожидает, что после этого, начавшаяся выполняться, задача будет сама по себе отменена.
Если так, то это неверное ожидание - CancelToken работает не так.

Автоматически он проверяется только один раз в момент запуска задачи на исполнение.
В общем случае, создание задачи и запуск её на исполнение - это разные по времени действия.
И если в этот промежуток токен будет отменён, то в момент запуска задачи будет выкинуто исключение и задача не поставится на исполнение.
В большинстве случаев задача создаётся и запускается почти одновременно методом Run или StartNew.
Но лаг между создание и запуском всё равно присутствует хоть и сведён к минимуму на сколько возможно.

Если же вам надо завершить уже начавшуюся исполняться задачу, то нужно в метод, исполняемый задачей, вставить "ручной" код периодической проверки токена и, если он отменён, выкидывать исключение TaskCanceledException.
1
0 / 0 / 0
Регистрация: 12.12.2021
Сообщений: 205
15.04.2022, 18:57  [ТС]
limeniye, cпасибо большое! Но у меня изменилась задача, посмотрите пожалуйста (прикрепляю проект), кнопка Отмена должна закрывать окно с Прогрессбаром, надо наверно как-то заблокировать поток, который запускает Прогрессбар
Вложения
Тип файла: zip 1504.zip (214.5 Кб, 0 просмотров)
0
0 / 0 / 0
Регистрация: 12.12.2021
Сообщений: 205
15.04.2022, 19:00  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если же вам надо завершить уже начавшуюся исполняться задачу, то нужно в метод, исполняемый задачей, вставить "ручной" код периодической проверки токена и, если он отменён, выкидывать исключение TaskCanceledException.
да, именно это нужно
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
15.04.2022, 19:20
Цитата Сообщение от Sun1212 Посмотреть сообщение
да, именно это нужно
Тогда нужно "вручную" периодически (например в цикле, если он есть) проверять отменён ли токен.
То есть разница с вариантом от limeniye, будет только в том, что он проверяет флаг, а вы будете проверять токен.

Добавлено через 2 минуты
И есть общепринятая разница в результатах проверки.
Если используете токен, то при обнаружении его отмены принято выкидывать исключение.
Если же проверяется флаг, то задача просто обрывается (return) с выводом (если надо) промежуточного результата.
0
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
15.04.2022, 19:44
Спасибо большое! Но у меня изменилась задача
Sun1212, бален, у Вас какие-то динамические задачи

Добавлено через 4 минуты
Элд Хасп, в каких случаях уместно использовать токен отмены, а в каких достаточно обычной переменной?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
15.04.2022, 20:31
Цитата Сообщение от limeniye Посмотреть сообщение
в каких случаях уместно использовать токен отмены, а в каких достаточно обычной переменной?
Токен отмены - это стандартизированный способ отмены задачи понятный всем без дополнительной документации.
Но, как я писал выше, на отмену задачи ожидается выброс исключению OperationCanceledException .
Такое поведение ожидаемо от отмены токена, так как при его применении всегда есть вероятность получить исключение при запуске задачи на исполнение.

Если же результатом отмены задачи должным быть просто выход из метода с промежуточным результатом, то использование токена отмены в такой ситуации не желательно, поскольку создаёт неожидаемое поведение.
В таком случае лучше использовать флаг отмены.
Но с флагом отмены тоже не всё так просто, поскольку из-за параллельности выполнения кеши методов не всегда синхронизируются.
См. одну одну из тем по этому вопросу: lock в условие или в цикле.
1
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
15.04.2022, 20:52
Цитата Сообщение от Sun1212 Посмотреть сообщение
кнопка Отмена должна закрывать окно с Прогрессбаром
Я просто сделал так:
- задал кнопке имя
XML
1
<Button x:Name="cancelButton" ... />
- При клике на кнопку я вызываю метод Close()
C#
1
2
3
4
5
6
7
8
    public partial class ProgressWindow : Window
    {
        public ProgressWindow()
        {
            InitializeComponent();
            cancelButton.Click += (s,e) => this.Close();
        }
    }
Если по феншую, то это не совсем корректное решение. Но я, всё-таки, не буду усложнять.
Вложения
Тип файла: zip ProgressBarMVVMStudySolution.zip (9.6 Кб, 2 просмотров)
1
15.04.2022, 21:01

Не по теме:

Цитата Сообщение от Элд Хасп Посмотреть сообщение
См. одну одну из тем по этому вопросу: lock в условие или в цикле.
Бегло глянул. Тема слишком интересна, чтобы уделить ей 5 минут. Думаю мне это придётся очень долго изучать.
Я ещё Рихтера не дочитал даже.
Вернусь к ней чуть позже -- сейчас другие приоритеты.

0
0 / 0 / 0
Регистрация: 12.12.2021
Сообщений: 205
15.04.2022, 21:54  [ТС]
Элд Хасп, посмотрите, пожалуйста:

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
public async Task<bool> Start(Action action)
        {
            this.Show();
 
           CancellationToken token = CancelTokenSource.Token;
 
           // await Task.Run(action, token);
 
 
            try
            {
                _task = Task.Run(() => action, new CancellationToken(true));
            }
            catch (TaskCanceledException)
            {
                 // Операция прервана;
            }
            return true;
        }
 
 public void buttinCancel_click()
        {
            _viewModel.ButtonEnabled = false;
 
            if (_task!=null && _task.IsCompletedSuccessfully)
 
                 CancelTokenSource.Cancel();
        }
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
15.04.2022, 22:52
Цитата Сообщение от Sun1212 Посмотреть сообщение
посмотрите,
Смысл ваших методов?
Где вы "толкаете" ProgressBar ?

Вам же нужно отменять action, значит проверку токена надо производит и в теле этого метода.

Должно быть нечто подобное:

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 CancelTokenSource  tokenSource = new();
        public async Task<bool> Start(Action<CancellationToken> action)
        {
            this.Show();
 
           CancellationToken token = tokenSource.Token;
 
             try
            {
                await Task.Run(() => action(token), token);
            }
            catch (TaskCanceledException)
            {
                 // Операция прервана;
            }
            return true;
        }
 
        public void buttinCancel_click()
        {
            _viewModel.ButtonEnabled = false;
 
            if (_task!=null && _task.IsCompletedSuccessfully)
            {
                 tokenSource.Cancel();
                 tokenSource = new();
            }
        }
И тело метода который что-то там делает, толкает ProgressBar и проверяет токен:
C#
1
2
3
4
5
6
7
8
9
    private void SomeMethod(CancellationToken token)
    {
         while( .....)
         {
              token.ThrowIfCancellation();
 
             // Some Code: чё-то вычисляется и толкается ProgressBar.
         }
    }
Добавлено через 11 минут
Sun1212, не обратил внимание.
Исключение нужно ловить базовое, а то можете пропустить отмену из метода:
C#
12
13
14
15
            catch (OperationCanceledException)
            {
                 // Операция прервана;
            }
1
0 / 0 / 0
Регистрация: 12.12.2021
Сообщений: 205
16.04.2022, 22:19  [ТС]
Элд Хасп, спасибо! Подскажите, пожалуйста, как преобразовать System.Action в System.Action<System.Threading.Cancellat ionToken>?

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
private async Task StartProcess(CancellationToken token)
        {
 
            ProgressWindow newWwindow = new ProgressWindow("Заголовок окна");
           
            Action action = () =>
            {
                newWwindow.Update("Создание A", 0);
                Thread.Sleep(3000);
                newWwindow.Update("Создание B", 50);
                Thread.Sleep(3000);
                newWwindow.Update("Финиш", 100);
            };
 
            try
            {
                await newWwindow.Start(action);
 
                newWwindow.Close();
            }
            catch (OperationCanceledException)
            {
 
            }   
        }
    }
Добавлено через 1 минуту
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public async Task<bool> Start(Action<CancellationToken> action)
        {
            this.Show();
 
            CancellationToken token = tokenSource.Token;
 
            try
            {
                await Task.Run(() => action(token), token);
            }
            catch (TaskCanceledException)
            {
                // Операция прервана;
            }
            return true;
        }
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
17.04.2022, 00:46
Цитата Сообщение от Sun1212 Посмотреть сообщение
как преобразовать System.Action в System.Action<System.Threading.Cancellat ionToken>?
Никак.
Action - это ссылка на метод без параметра.
А вам нужен метод проверяющий токен.

И вы злоупотребляете делегатами, асинхронными методоми.
Основа любого вычисления - это синхронный метод.
Объявляйте их явно и если будет нужно то потом уже завернёте в задачу.
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
private static void ProgressWindowUpdate(ProgressWindow window, CancellationToken token)
{
    token.ThrowIfCancellation();
    window.Update("Создание A", 0);
 
    // Thread.Sleep(3000);
    for(int i = 0; i < 3000; i+=100)
    {
        token.ThrowIfCancellation();
        Thread.Sleep(100);
    }
 
    token.ThrowIfCancellation();
    window.Update("Создание B", 50);
 
    // Thread.Sleep(3000);
    for(int i = 0; i < 3000; i+=100)
    {
        token.ThrowIfCancellation();
        Thread.Sleep(100);
    }
 
    token.ThrowIfCancellation();
    window.Update("Финиш", 100);
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
private async Task StartProcessAsync()
{
 
    ProgressWindow newWindow = new ProgressWindow("Заголовок окна");
 
    // try Здесь не нужно, поскольку в Start все исключения обрабатываются.
 
    // Токен будет создаваться в методе Start
    boll result = await newWwindow.Start(token =>  ProgressWindowUpdate(newWindow, token));
 
    newWindow.Close();
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public async Task<bool> Start(Action<CancellationToken> action)
{
    this.Show();
 
    CancellationToken token = tokenSource.Token;
 
    try
    {
        await Task.Run(() => action(token), token);
       return true;
    }
    catch  // Если обрабатываются все исключения, то тип указывать не надо
    {
        // Операция прервана;
       return false;
     }
}
Добавлено через 6 минут
Sun1212, и как-то запутано, мне кажется, у вас методы объявляются.
Где у вас "толкается" ProgressBar? В этом методе window.Update(....)?

Если да, то он что делает всего два шага?
1
0 / 0 / 0
Регистрация: 12.12.2021
Сообщений: 205
17.04.2022, 07:56  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Где у вас "толкается" ProgressBar? В этом методе window.Update(....)?
да, в этом методе "толкается" ProgressBar, два шага - потому что это тест, в реальной задаче будет гораздо больше.

Можно заменить token.ThrowIfCancellation(); (ошибка выдается) на token.ThrowIfCancellationRequested(); ?
0
0 / 0 / 0
Регистрация: 12.12.2021
Сообщений: 205
17.04.2022, 08:05  [ТС]
Элд Хасп, что-то у меня всё равно не получается, кнопка Отмены не работает...Если не трудно, можете посмотреть мой проект?
Вложения
Тип файла: zip 1704.zip (215.2 Кб, 3 просмотров)
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
17.04.2022, 12:06
Цитата Сообщение от Sun1212 Посмотреть сообщение
Можно заменить token.ThrowIfCancellation(); (ошибка выдается) на token.ThrowIfCancellationRequested(); ?
Да.
Писал здесь - поэтому ошибку не видел...
Правильно ThrowIfCancellationRequested.

Цитата Сообщение от Sun1212 Посмотреть сообщение
можете посмотреть мой проект
Посмотрю.
Но на будущее лучше выкладывайте через Гит.
Архив, чтобы посмотреть, требуется загружать на комп в Студию, что не всегда удобно и возможно.
На Гите можно посмотреть без загрузки в браузере.

Добавлено через 41 минуту
Sun1212, вот здесь Command="{Binding buttonCancel_Click}" buttonCancel_Click - это кликер, а не команда.
Для WPF должно быть Command="buttonCancel_Click".
Но у вас Avalonia и копилятор не может найти кликер.

Вы знаете как кликеры в XAML нужно задавать?

Добавлено через 18 минут
Sun1212, так же у вас неверно работает сама логика в CB.
В кликере вы проверяете поле _task, но вы нигде не задаёте ему значение, поэтому кликер у вас никогда не будет срабатывать.

Пример реализации:

Подсоединение кликера в Шарпе:
XML
17
18
19
            <Button x:Name="buttonCancel" Width="70" Height="30"
                    IsEnabled="True" Content="Отмена"
                    Margin="20,20,5,5" HorizontalAlignment="Center" />
C#
21
22
23
24
25
26
        public ProgressWindow(string title) : this()
        {
            InitializeComponent();
            DataContext = new FileManagerViewModel();
            buttonCancel.Click += (s, e) => buttinCancel_click();
        }
Сам кликер:
C#
47
48
49
50
51
52
53
54
55
56
        public void buttinCancel_click()
        {
            _viewModel.ButtonEnabled = false;
 
            if (_task != null && !_task.IsCompletedSuccessfully)
            {
                tokenSource.Cancel();
                tokenSource = new();
            }
        }
Задание значения _task в await:
C#
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
        public async Task<bool> Start(Action<CancellationToken> action)
        {
            this.Show();
 
            CancellationToken token = tokenSource.Token;
 
            try
            {
                await (_task = Task.Run(() => action(token), token));
                return true;
            }
            catch  // Если обрабатываются все исключения, то тип указывать не надо
            {
                // Операция прервана;
                return false;
            }
        }
2
0 / 0 / 0
Регистрация: 12.12.2021
Сообщений: 205
17.04.2022, 14:44  [ТС]
Элд Хасп, cпасибо Вам большое! Всё получилось!!!
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
17.04.2022, 14:50
Цитата Сообщение от Sun1212 Посмотреть сообщение
Всё получилось!!!
Кликер как задали? В XAML или Шарпе?
0
0 / 0 / 0
Регистрация: 12.12.2021
Сообщений: 205
17.04.2022, 14:57  [ТС]
Элд Хасп, кликер задала в Шарпе

XML
1
 <Button x:Name="buttonCancel" Width="70" Height="30"..../>
Цитата Сообщение от Элд Хасп Посмотреть сообщение
public ProgressWindow(string title) : this()
{
InitializeComponent();
DataContext = new FileManagerViewModel();
buttonCancel.Click += (s, e) => buttinCancel_click();
}
0
0 / 0 / 0
Регистрация: 12.12.2021
Сообщений: 205
18.04.2022, 12:36  [ТС]
Элд Хасп, скажите, пожалуйста, как сделать метод ProgressWindowUpdate без цикла for?

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
private static void ProgressWindowUpdate(ProgressWindow window, CancellationToken token)
{
    token.ThrowIfCancellation();
    window.Update("Создание A", 0);
 
    // Thread.Sleep(3000);
    for(int i = 0; i < 3000; i+=100)
    {
        token.ThrowIfCancellation();
        Thread.Sleep(100);
    }
 
    token.ThrowIfCancellation();
    window.Update("Создание B", 50);
 
    // Thread.Sleep(3000);
    for(int i = 0; i < 3000; i+=100)
    {
        token.ThrowIfCancellation();
        Thread.Sleep(100);
    }
 
    token.ThrowIfCancellation();
    window.Update("Финиш", 100);
}
Такой вариант правильный?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private static void ProgressWindowUpdate(ProgressWindow window, CancellationToken token)
{
    if (!token.IsCancellationRequested)
   {
      //что-то будет делаться
       window.Update("Создание A", 0);
    } 
   else token.ThrowIfCancellationRequested;
 
    if (!token.IsCancellationRequested)
   {
      //что-то будет делаться
       window.Update("Создание B", 50);
    } 
   else token.ThrowIfCancellationRequested;
 
   if (!token.IsCancellationRequested)
   {
      //что-то будет делаться
      window.Update("Финиш", 100);
    } 
   else token.ThrowIfCancellationRequested;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.04.2022, 12:36

Mvvm
Форумчане помогите разобраться есть простенькая модель public partial class Category:ViewModelBase { private int...

MVVM
Объясните пожалуйста следующие строки 1)Представление является подписчиком на событие изменения значений свойств или команд,...

MVVM
Здравствуйте, я в среде WPF нахожусь очень мало, посмотрел книжки, решил читать Мэтью Макдональда, стоит ли мне сразу изучать MVVM или...

x:Name в MVVM
Добрый день, как обращаться к объектам из VM по их x:Name? Например, у меня есть канвас в который я докидываю картинки по нажатию...

MVVM
Добрый день! Пытаюсь написать программу в стиле MVVM. Вопрос такой: как передать SelectedItem TreeView из xaml с помощью Binding в...


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru