xin9le.net

Microsoft の製品/技術が大好きな Microsoft MVP な管理人の技術ブログです。

Rx入門 (17) - 入力文字の遅延表示

しばらく空いてしまいましたが、落ち穂拾いと称してマッタリのんびりゆったりとやっていこうと思います。今回からはRxを利用した簡単な応用例をいくつか載せて行こうと思います。サンプルコードはサンプルコード集の中に随時追加して行きますので、ぜひ実際に実行してみてください。

今回の内容は、昔@neueccさんがどこかの勉強会でやっていた (ような気がする) サンプルで、入力した文字が少し遅れて表示されるというちょっと奇妙で面白い例題です。

サンプルコード

サンプルはWPFで書いています。XAMLは以下の通りで、入力用のTextBoxと表示用のTextBlockがあるだけです。

<Window x:Class="Sample36_DelayText.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Sample36_DelayText" Width="300" SizeToContent="Height">
    <StackPanel>
        <TextBox Name="input" />
        <TextBlock Name="display" />
    </StackPanel>
</Window>

あとはコンストラクタに入力イベントにおける処理の遅延を書くだけです。Observable.Delayメソッドが今回のキモで、指定した時間だけ値の通知を遅らせてくれるものです。このとき、遅延した後のコードはUIスレッドでなくなるので、Observable.ObserveOnメソッドでUIスレッドに戻しています。また、ここでは入力された文字をすべて大文字に変換するということもしています。

using System;
using System.Reactive.Linq;
using System.Windows;
using System.Threading;
 
namespace Sample36_DelayText
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
            Observable.FromEventPattern(this.input, "TextChanged")
            .Select(_ => this.input.Text.ToUpper())       //--- 大文字に変換
            .Delay(TimeSpan.FromMilliseconds(500))        //--- 0.5秒遅延
            .ObserveOn(SynchronizationContext.Current)    //--- UIスレッドに戻す
            .Subscribe(text => this.display.Text = text); //--- 表示
        }
    }
}

実行例

実行すると以下のようになります。以下の画像では表示遅延中のため後半部分が欠けていますが、すぐに表示されました。

DelayText

「こんなのいつ使うんですか?」と聞かれても「わかりません...」としか答えられませんが、Rxの面白さは体感できますね!