UI上的多线程WPF

本文关键字:WPF 多线程 UI | 更新日期: 2023-09-27 17:49:42

在我的c# WPF应用程序中,我有一个DataGrid,在它的正上方有一个TextBox,供用户搜索和过滤网格。如果用户键入速度很快,那么直到他们键入后2秒才会出现文本,因为UI线程忙于更新网格。

由于大多数延迟都在UI端(例如,过滤数据源几乎是即时的,但重新绑定和重新渲染网格很慢),多线程没有帮助。然后,我尝试在网格更新时将网格的调度程序设置为较低级别,但这也没有解决问题。这里有一些代码…对于如何解决这类问题有什么建议吗?

string strSearchQuery = txtFindCompany.Text.Trim();
this.dgCompanies.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(delegate
    {
        //filter data source, then
        dgCompanies.ItemsSource = oFilteredCompanies;
    }));

UI上的多线程WPF

使用ListCollectionView作为您的ItemsSource为网格和更新过滤器的工作比重新分配ItemsSource快得多。

下面的示例通过简单地刷新setter中的View来过滤100000行,没有明显的延迟。

ViewModel

class ViewModel
    {
        private List<string> _collection = new List<string>(); 
        private string _searchTerm;
        public ListCollectionView ValuesView { get; set; }
        public string SearchTerm
        {
            get
            {
                return _searchTerm;
            }
            set
            {
                _searchTerm = value;
                ValuesView.Refresh();
            }
        }
        public ViewModel()
        {
            _collection.AddRange(Enumerable.Range(0, 100000).Select(p => Guid.NewGuid().ToString()));
            ValuesView = new ListCollectionView(_collection);
            ValuesView.Filter = o =>
                {
                    var listValue = (string)o;
                    return string.IsNullOrEmpty(_searchTerm) || listValue.Contains(_searchTerm);
                };
        }
    }
<<p> 视图/strong>

<TextBox Grid.Row="0" Text="{Binding SearchTerm, UpdateSourceTrigger=PropertyChanged}" />
<ListBox ItemsSource="{Binding ValuesView}"
         Grid.Row="1" />

如果你的目标是。net 4.5,一个选项是在你的TextBox上设置Delay属性,这将阻止设置源值,直到满足一定的时间阈值(直到用户停止输入)。

<TextBox Text="{Binding SearchText, Delay=1000}"/>

在没有用户输入设置源值后等待1秒。

另一个选择是让一个按钮触发你的过滤器/搜索,而不是当文本框发生变化时。