应用程序解析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的新手。如何找到问题?
答案 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>
的文档。