简体   繁体   English

UI上的多线程WPF

[英]Multi-threading WPF on the UI

In my C# WPF application I have a DataGrid and right above it there is a TextBox for the user to search and filter the grid as they type. 在我的C#WPF应用程序中,我有一个DataGrid ,正上方有一个TextBox ,供用户在键入时搜索和过滤网格。 If the user types fast though, no text will appear until 2 seconds after they type because the UI thread is too busy updating the grid. 如果用户快速键入,则在键入后2秒内不会显示任何文本,因为UI线程太忙于更新网格。

Since most of the delay is all on the UI side (ie filtering the datasource is nearly instant, but rebinding and re-rendering the grid is slow), multi-threading has not been helpful. 由于大部分延迟都在UI端(即过滤数据源几乎是即时的,但重新绑定和重新渲染网格很慢),多线程并没有帮助。 I then tried setting the dispatcher of just the grid to be at a lower level while the grid gets updated, but this didn't solve the issue either. 然后我尝试将网格的调度程序设置为较低级别,同时网格更新,但这也没有解决问题。 Here's some code... Any suggestions on how to solve this type of problem? 这里有一些代码......关于如何解决这类问题的任何建议?

string strSearchQuery = txtFindCompany.Text.Trim();

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

Using a ListCollectionView as your ItemsSource for the grid and updating the Filter works much faster than re-assigning the ItemsSource. 使用ListCollectionView作为GridS的ItemsSource并更新Filter比重新分配ItemsSource要快得多。

The example below filters 100000 rows with no apparent lag by simply refreshing the View in the setter for the search term text property. 通过简单地刷新搜索词文本属性的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);
                };
        }
    }

View 视图

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

<ListBox ItemsSource="{Binding ValuesView}"
         Grid.Row="1" />

If you are targeting .net 4.5, an option is to set the Delay property on your TextBox which will prevent setting the source value until a certain time threshold is met (until the user stops typing). 如果您的目标是.net 4.5,则选项是在TextBox上设置Delay属性,这将阻止设置源值,直到满足特定时间阈值(直到用户停止键入)。

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

This waits for 1 second after there is no user input to set the source value. 在没有用户输入来设置源值之后等待1秒。

Another option is to have a button trigger your filter/search instead of when the textbox changes. 另一个选项是让按钮触发您的过滤器/搜索,而不是文本框更改时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM