我的应用中有一个很长的谓词过滤。 我需要以百分比显示确切的进度,但我无法在过滤器中获得任何进展。
public ICollectionView viewSource { get; set; }
viewSource = CollectionViewSource.GetDefaultView(Photos);
// this line takes 30 seconds
viewSource.Filter = i => (... & ... & .... long list of conditions)
答案 0 :(得分:4)
您可以将viewSource.Filter
过滤功能包装在BackgroundWorker
线程上处理的方法中。如果您能够确定要过滤的objects
的数量,则可以增加counter
,它可以与起始计数一起用于提供进度。
修改强>
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Windows.Data;
using System.Windows.Threading;
public partial class MainWindow : Window
{
private readonly Random random = new Random();
private BackgroundWorker backgroundWorker;
private ObservableCollection<int> CollectionOfInts { get; set; }
private ICollectionView ViewSource { get; set; }
public MainWindow()
{
InitializeComponent();
this.CollectionOfInts = new ObservableCollection<int>();
var nextRandom = this.random.Next(1, 200);
for (var i = 0; i <= nextRandom + 2; i++)
{
this.CollectionOfInts.Add(this.random.Next(0, 2000));
}
this.ViewSource = CollectionViewSource.GetDefaultView(this.CollectionOfInts);
this.ProgressBar.Maximum = this.CollectionOfInts.Count;
}
private void RunFilter()
{
this.ViewSource.Filter = LongRunningFilter;
}
private bool LongRunningFilter(object obj)
{
try
{
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
new Action(() => this.ProgressBar.Value++)
);
var value = (int) obj;
Thread.Sleep(3000);
return (value > 5 && value < 499);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return false;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
try
{
this.ProgressBar.Value = 0;
this.backgroundWorker = new BackgroundWorker();
this.backgroundWorker.DoWork += delegate { RunFilter(); };
this.backgroundWorker.RunWorkerAsync();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
这里的基本原则是我知道有多少objects
我必须过滤(this.CollectionOfInts.Count
),所以这是我的Maximum
值(100%)。我在BackgroundWorker
线程上开始过滤。使用BackgroundWorker
启动RunWorkerAsync
会调用RunFilter
方法,而LongRunningFilter
方法会调用实际执行过滤的Thread.Sleep
(我在其中放置LongRunningFilter
来模拟时间消费过滤器)。 ViewSource
中的每个对象都会调用increment
一次,因此可以用counter
Maximum
来告知我们当前正在进行的迭代。将此与已知的{{1}}结合使用,即可获得进展。
我意识到这并不是你的实际问题的确切方式,但是,它显示了这个概念。