我正在开发一个Xamarin Forms移动应用程序,它有一个包含SearchBar,ListView和Map控件的页面。列表视图包含一个地址列表,这些地址在地图上反映为引脚。
当用户在SearchBar中键入时,ListView会自动更新(通过ViewModel绑定)。过滤列表数据源的ViewModel方法看起来像这样......
void FilterList()
{
listDataSource = new ObservableCollection<location>(
locationData.Where(l => l.Address.Contains(searchBar.Text))
);
// ***** Now, update the map pins using the data in listDataSource
}
我希望更新Map,因为ListView被过滤,但不是在每个按键上,因为这可能每秒发生多次。基本上,我想在更新Map之前在每个FilterList事件中进行“滚动暂停”。在伪代码中......
// ***** Now, update the map pins using the data in listDataSource
if (a previously-requested map update is pending)
{
// Cancel the pending map update request
}
// Request a new map update in 1000ms using [listDataSource]
可以使用可移植类库中提供的Stopwatch类来完成此操作,但我怀疑使用Tasks可以实现更清晰/更好的方法。
任何人都可以建议一个“更聪明”PCL兼容的方式来做到这一点?
你可以试试 :
await Task.Delay(2000);
就像你说的那样,这可以使用Tasks
和异步编程以非常干净的方式完成。
你会想看看它:http://msdn.microsoft.com/en-us/library/hh191443.aspx
这是一个例子:
public async Task DelayActionAsync(int delay, Action action)
{
await Task.Delay(delay);
action();
}
这就是我所做的,它适用于我的Xamarin Form应用程序。
public string Search
{
get { return _search; }
set
{
if (_search == value)
return;
_search = value;
triggerSearch = false;
Task.Run(async () =>
{
string searchText = _search;
await Task.Delay(2000);
if (_search == searchText)
{
await ActionToFilter();
}
});
}
}
我把这个'搜索'属性绑定到我的输入字段。每当用户过滤某些内容时,代码等待1秒钟,然后将新的文本字段与之前1秒之前的字段进行比较。假设字符串相等意味着用户已停止输入文本,现在可以触发代码进行过滤。
按钮点击的另一种很棒的方法是,
public async void OnButtonClickHandler(Object sender, EventArgs e)
{
try
{
//ShowProgresBar("Loading...");
await Task.Run(() =>
{
Task.Delay(2000); //wait for two milli seconds
//TODO Your Business logic goes here
//HideProgressBar();
});
await DisplayAlert("Title", "Delayed for two seconds", "Okay");
}
catch (Exception ex)
{
}
}
async
和await
密钥很重要,假设您正在处理多线程环境。
有another方式:
new Handler().PostDelayed(() =>
{
// hey, I'll run after 1000 ms
}, 1000);
当然你也可以使用以下版本:
var handler = new Handler();
var action = () =>
{
// hey, I'll run after 1000 ms
};
handler.PostDelayed(action, 1000);