« 当たった | トップページ | 28回目 »

2021年1月19日 (火)

なんちゃってインクリメンタルサーチ

雲多めだったけれど、今日もそれなりにいい天気。

今日の朝は、ギリギリ氷点下ではなかったようだ。

 

インクリメンタルサーチをやりたいなぁ、と思った。

でも、実現したい処理は、表示件数が多く、連続して文字を入力すると、その処理を実施している最中に、次の処理が走ることにより、処理結果に不整合が生じる。

だから、一文字ごとに処理をすることは出来ない、という結論になった。

ネットで検索してみたけれど、あまり需要がないのか、これという情報を得られなかった。

ムムム・・・
なんかいい方法はないものか?と考えに考えた。

ひねりにひねって出来たのが、「なんちゃってインクリメンタルサーチ」!

VB.NETでやったので、そのコードを。

Private Shared SleepCount As Integer = 0

Private Async Sub TaskDelay()

  SleepCount += 1
  Await Task.Delay(200)
  SleepCount -= 1

  If SleepCount <= 0 Then
    'ここに処理を書く
  End If
End Sub

上記のコーディングのポイントは2つ。

「Await Task.Delay」を使っているところと、カウンターを使って、処理を行うか行わないかの判断をしているところ。

例えば、VB.NETのTextBoxで、下記のようなAddhandlerの場合。

Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged

  TaskDelay()

End Sub

これは、TextBoxに、一文字入力されるごとに処理が実行される関数。

出来れば、このTextBoxが、文字入力完了を検知してくれればいいのだけれど、どうもそういう機能はないようだ。
最後の文字を入力して、何秒後に処理実行というのをしたかったんだよね。

それが出来ないようだったので、今回のような仕組みを考え出した。

閑話休題。

この中に、上記の「TaskDelay」関数を記述しておけばいい。
(関数名は何でもいい。説明のために、そういう関数名にしているだけなので。)

一文字入力するごとに、これが呼び出される。

すると、SleepCountっていうのがカウントアップされる。

次に、Await Task.Delayで、上記の場合だと、200ms待ちが発生する。
この数字は、お好きな数字を。
あまり短すぎると、本当に実行させたい処理がすぐに走ってしまうので注意。

それが終わると、SleepCountがカウントダウンされる。

そのSleepCountが0になった時だけ、実行させたい処理が走る。

これだと、毎回0になるから意味ないじゃない!って思うかもしれないけれど、Await Task.Delayは非同期で遅延するので、投げっぱなしになる。

例えば、ダダダーと素早く10文字入力すると、10個のTaskDelay関数が一気に走る。

その時、SleepCountは、一気にカウントアップされ、既定の時間後、それぞれのTaskDelay関数がカウントダウンし、最後のものが走った時だけ、SleepCountは0になるという仕組み。

こうすることで、余計な処理を走らせないで済む、つまり、実行させたい処理は1度だけ走らせることが出来るし、処理の不整合は起こらない。

実際にはインクリメンタルサーチではないけれど、最終的には、必要な情報が表示されればいいのだから、このなんちゃってインクリメンタルサーチでも十分なのである。

ちょっとした工夫で、似たようなことが出来るようになったのは、我ながらすごい!と思ったのである。(笑)

|

« 当たった | トップページ | 28回目 »

パソコン・インターネット」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




« 当たった | トップページ | 28回目 »