Je développe une application mobile Xamarin Forms, qui comporte une page contenant un contrôle SearchBar, un contrôle ListView et un contrôle Map. La vue liste contient une liste d'adresses, qui sont reflétées sous forme de broches sur la carte.
Lorsque l'utilisateur tape dans la barre de recherche, ListView est automatiquement mis à jour (via la liaison ViewModel). La méthode ViewModel qui filtre la source de données pour la liste ressemble à ceci ...
void FilterList()
{
listDataSource = new ObservableCollection<location>(
locationData.Where(l => l.Address.Contains(searchBar.Text))
);
// ***** Now, update the map pins using the data in listDataSource
}
Je souhaite mettre à jour la carte car le ListView est filtré, mais pas sur CHAQUE pression, cela pouvant se produire plusieurs fois par seconde. Essentiellement, je souhaite une "pause progressive" dans chaque événement FilterList avant la mise à jour de la carte. En pseudo-code ...
// ***** 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]
Il est possible de le faire en utilisant Stopwatch class, qui est disponible dans les bibliothèques de classes portables, mais je soupçonne qu’il existe un moyen plus propre/meilleur de le faire en utilisant Tasks .
Quelqu'un peut-il suggérer un "plus intelligent" compatible PCL moyen de le faire?
tu peux essayer :
await Task.Delay(2000);
Comme vous l'avez dit, ceci peut être accompli de manière très propre en utilisant la programmation Tasks
et async.
Vous voudrez lire à ce sujet: http://msdn.Microsoft.com/en-us/library/hh191443.aspx
Voici un exemple:
public async Task DelayActionAsync(int delay, Action action)
{
await Task.Delay(delay);
action();
}
Voici ce que j'ai fait et cela fonctionne dans mes applications 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();
}
});
}
}
J'ai cette propriété 'Recherche' liée à mon champ Entrée. Chaque fois que l'utilisateur filtre quelque chose, le code attend 1 seconde, puis compare le nouveau champ Texte avec le champ qu'il était avant 1 seconde avant. En supposant que la chaîne soit égale, cela signifie que l'utilisateur a cessé de saisir le texte et que le code peut maintenant être déclenché pour filtrer.
Une autre excellente méthode de clic sur le bouton est,
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)
{
}
}
Les clés async
et await
sont importantes, supposons si vous travaillez dans un environnement multithread.