Xamarinフォームモバイルアプリを開発しています。これには、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
}
ListViewがフィルターされているときにマップを更新したいのですが、1秒に複数回発生する可能性があるため、すべてのキーを押す必要はありません。基本的に、マップが更新される前に、各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互換これを行う方法を提案できますか?
単純な遅延の問題は、遅延の期限が切れたときにキューに入れられる一連のイベントを取得できることです。遅延の実行中に発生したイベントを破棄するロジックを追加できます。より高いレベルでロジックを宣言する場合は、 Reactive Extensions を使用できます。
あなたが試すことができます :
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秒前のフィールドと比較します。文字列が等しいと仮定すると、ユーザーがテキストの入力を停止し、コードをトリガーしてフィルターできるようになります。
ボタンクリック時のもう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
キーは重要です。マルチスレッド環境で作業しているとしましょう。