Обновление ProgressBar в главном окне WPF из другого класса (делегат) - PullRequest
0 голосов
/ 10 июля 2019

Приложение анализирует файлы CSV и XML. Поскольку файлов много, индикатор выполнения должен обновляться шаг за шагом. Приложение WPF в основном для пользовательского интерфейса и связанных с ним событий. Другой класс фактически реализует логику.

Я применил делегат для обновления значения. Делегат получает целочисленное значение для обновления индикатора выполнения, но пользовательский интерфейс не показывает изменений.

MainWindow.xaml:


    <Grid Margin="20">
                <ProgressBar Height="50" Width="400" Minimum="0" Maximum="100"  Name="pbStatus" />
                <TextBlock Text="{Binding ElementName=pbStatus, Path=Value, StringFormat={}{0:0}%}" HorizontalAlignment="Center" VerticalAlignment="Center" />
            </Grid>

MainWindow.xaml.cs:


    public partial class MainWindow : Window
    {
       Class2 fileConvert = new Class2();

       public MainWindow()
            {
                InitializeComponent();
                fileConvert.UpdateProgress += UpdateProgress;

            }

    private void UpdateProgress(int ProgressPercentage)
            {
                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate ()
                {
                    pbStatus.Value = ProgressPercentage; 
                }));
            }
    private void BtnConvert_Click(object sender, RoutedEventArgs e)
    {
       var newFiles = fileConvert.ProcessConvertInfo(allFiles, destiString);
    }
    }

Class2:


    public class Class2
    {
    public delegate void UpdateProgressDelegate(int ProgressPercentage);
    public event UpdateProgressDelegate UpdateProgress;

    public List<string> ProcessConvertInfo(string[] csvfiles, string destiPath)
    {
    foreach (string filePath in csvfiles)
    {
    //Progressbar value
     int i = Array.IndexOf(csvfiles, filePath);
    //Passing value to Delegate
    UpdateProgress(i++);
    }
    }
    }

Этот метод ниже в MainWindow.xaml.cs получает значение ProgressPercentage для каждой итерации файлов в списке другого Class2 и назначается значению индикатора выполнения.

    private void UpdateProgress(int ProgressPercentage)
            {
                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate ()
                {
                    pbStatus.Value = ProgressPercentage; 
                }));
            }

Индикатор выполнения ничего не показывает. Я не получаю никакой ошибки. Я новичок в WPF. Как я могу найти проблему?

1 Ответ

1 голос
/ 10 июля 2019

Ваш код выглядит так, как будто он блокирует поток пользовательского интерфейса.Возможно, вы заблокировали приложение.Но помимо этого код должен работать.

Вы должны выполнить операцию блокировки асинхронно:

Class2.cs

public async Task<List<string>> ProcessConvertInfoAsync(string[] csvfiles, string destiPath)
{
    return await Task.Run(() =>
    {
        foreach (string filePath in csvfiles)
        {
            //Progressbar value
            int i = Array.IndexOf(csvfiles, filePath);

            //Passing value to Delegate
            UpdateProgress(i++);
        }
        return csvfiles.ToList();
    });
}

MainWindow.xaml.cs

private async void BtnConvert_Click(object sender, RoutedEventArgs e)
{
   var newFiles = await fileConvert.ProcessConvertInfoAsync(allFiles, destiString);
}

Чтобы избежать накладных расходов кода и включить дополнительные функции, я рекомендую использовать шаблон Progress<T>.Я думаю, что ваш подход очень близок к этому.Ключ класса Progress<T> заключается в том, что он автоматически захватывает SynchronizationContext при создании.Это исключает использование диспетчера.Progress<T> также позволяет отменить отчет о проделанной работе.Код также будет выглядеть выразительным и чистым.
В этой статье Microsoft Async в 4.5: Включение выполнения и отмены в API-интерфейсах Async подробно объясняется, как его использовать.Ссылка из документации Progress<T>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...