从另一个类(委托)更新WPF MainWindow中的ProgressBar

时间:2019-07-10 15:02:27

标签: c# wpf delegates progress-bar

应用程序解析CSV和XML文件。由于文件很多,因此必须逐步更新进度条。 WPF应用程序主要用于UI和相关事件。另一个类实际上实现了逻辑。

我已应用Delegate更新值。委托接收到用于更新进度条的整数值,但UI未显示任何更改。

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中的此方法为另一个Class2列表中的文件的每次迭代接收ProgressPercentage值,并将其分配给progressbar值。

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

进度条不显示任何内容。我没有任何错误。我是WPF的新手。如何找到问题?

1 个答案:

答案 0 :(得分:1)

您的代码似乎阻塞了UI线程。您可能已经僵持了该应用程序。但是除此之外,代码应该可以工作。

您应该异步运行阻止操作:

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。这消除了对Dispatcher的使用。 Progress<T>还可以取消进度报告。代码也看起来富有表现力和简洁。
Microsoft的这篇文章Async in 4.5: Enabling Progress and Cancellation in Async APIs详细说明了如何使用它。链接来自Progress<T>的文档。