【问题标题】:Keyboard freezes on Xamarin.Forms SearchbarXamarin.Forms 搜索栏上的键盘冻结
【发布时间】:2016-04-02 16:25:36
【问题描述】:

我有一个自定义实现的控件,它非常占用内存(它基本上为每个组显示一个组标题和一个手风琴控件)。 CustomControls AccordionControlGrouping 和 AccordionControl 都继承自 StackLayout,因此我实现了自己的可绑定 ItemsSource。当 ItemsSource 更改时,我会主动更改控件的视图。 我现在已经优化了这个更改(使用 LINQ 和 BinarySearch 之类的东西)从 5sec 开始。每次搜索到 0.8 秒。

这本身不是问题,但是每次用户输入一个键时,键盘都会冻结,因此非常不方便搜索。

我的 SearchBar 像这样绑定到 ViewModel 的命令

<SearchBar x:Name="EventSearchBar"
             Text="{Binding SearchText}"
             SearchCommand="{Binding SearchCommand}"
             Placeholder="Suche"/>

搜索命令

private Xamarin.Forms.Command _searchCommand;
public System.Windows.Input.ICommand SearchCommand
{
    get
    {
        _searchCommand = _searchCommand ?? new Xamarin.Forms.Command(UpdateAccordionControlGrouping, CanExecuteSearchCommand);
        return _searchCommand;
    }
}
private bool CanExecuteSearchCommand()
{
    return true;
}

SearchText 属性

private string _searchText = string.Empty;
public string SearchText
{
    get { return _searchText; }
    set
    {
        if (_searchText != value)
        {
            _searchText = value ?? string.Empty;
            RaisePropertyChanged(nameof(SearchText));

            // Perform the search
            if (SearchCommand.CanExecute(null))
                SearchCommand.Execute(null);
        }
    }
}

UpdateAccordionControlGrouping

private void UpdateAccordionControlGrouping()
{
  // Do some LINQ stuff to group and filter a global collection of data.
  // And raise the #OnPropertyChanged event for the ItemsSource of my 
  // custom control.
}

现在如何使整个过程异步?

我已经查看了this article,但它对我不起作用。

【问题讨论】:

  • 这与 async-await 有什么关系?
  • 您是否在每次更改文本时都在积极更新列表?
  • 抱歉,回复晚了。我认为这与 async-await 高度相关,因为为了提供两个线程彼此独立工作的解决方案,您需要异步,不是吗?是的,每次文本更改时,我都会主动更新列表(即 ItemsSource)。不幸的是,我忘了提及,customControl“AccordionControlGrouping”以及CustomControl“AccordionControl”都继承自StackLayouts。 (有关详细信息,请参阅帖子的编辑)

标签: c# xaml data-binding async-await xamarin.forms


【解决方案1】:

要异步运行您的方法“UpdateAccordionControlGrouping()”,您可以这样做:

private async Task UpdateAccordionControlGrouping()
{
    var newgrouping = await Task.Run(() => 
        {
            //do CPU bound work here
            return newgrouping;
        });
   // assign newgrouping to the correct control
}

请注意,如果您需要更改视图中的任何数据(绑定等),您可能会收到 CrossThreadException。您需要使用Dispatcher,然后如下所示:Dispatcher.Dispatch on the UI thread

如果您使用 MvvmLight,您可以使用 DispatchHelper Simple example of DispatcherHelper

【讨论】:

  • 首先感谢您的回复!我现在已经尝试过这种方法,并且发现现在填充正在异步进行。但是从逻辑上讲,当人口正在执行并且用户按下另一个键时,该键会挂起,因为 gui 等待后台人口完成。我将按如下方式解决此问题。每次用户按键且填充仍在进行中时,都会取消填充并启动新的填充线程。
  • @Shanakor 除了使用async 和await 我认为你应该使用loader 来逃避freezing 问题以及debouncing 在你的方法中,它会限制数量您的处理程序函数将重新填充数据源的次数,它的性能会提高。您可以在这篇精彩的文章 link 中了解如何在 Xamarin 中实现 debouncing。
猜你喜欢
  • 2011-03-08
  • 2019-02-19
  • 2016-11-18
  • 1970-01-01
  • 2013-12-03
  • 2017-04-06
  • 2013-01-19
  • 2012-08-09
  • 1970-01-01
相关资源
最近更新 更多