入門ばっかりで飽きてきたので、応用的なものを作ってみました。因みにWPFアプリケーションです。
各種イベントを監視するObservableを用意します。
// マウスダウンイベント var mouseDown = Observable.FromEvent( (EventHandler<MouseButtonEventArgs> h) => new MouseButtonEventHandler(h), h => this.MouseDown += h, h => this.MouseDown -= h); // マウスむーぶイベント var mouseMove = Observable.FromEvent( (EventHandler<MouseEventArgs> h) => new MouseEventHandler(h), h => this.MouseMove += h, h => this.MouseMove -= h); // マウスアップイベント var mouseUp = Observable.FromEvent( (EventHandler<MouseButtonEventArgs> h) => new MouseButtonEventHandler(h), h => this.MouseUp += h, h => this.MouseUp -= h);
これらのイベントをベースにいろいろ組み立てていきます。
// アイテムのZIndex int zIndex = 0; // ボタンダウン開始点 Point startPos = default(Point); // クリック開始点の記録とマウスのキャプチャ mouseDown .Select(e => e.EventArgs.GetPosition(this)) .Subscribe(p => { this.CaptureMouse(); startPos = p; }); // マウスがリリースされたタイミングでキャプチャをリリース // そして、矩形を作成してCanvasに追加 mouseUp.Select(e => e.EventArgs.GetPosition(this)) .Subscribe(p => { this.ReleaseMouseCapture(); var r = CreateRectangle(startPos, p, zIndex++); layoutRoot.Children.Add(r); }); // マウスを動かしてる箇所を通知してくれる var movePoints = mouseMove .Select(e => e.EventArgs.GetPosition(this)); // マウスが押されるまでスキップして、マウスがアップされるまで // 通知する。そして、それを繰り返す。 var drag = movePoints .SkipUntil(mouseDown) .TakeUntil(mouseUp) .Repeat(); // ドラッグ中に、draggingという名前の半透明の矩形を移動させ続ける drag.Subscribe(p => SetRectangle(dragging, startPos, p, zIndex));
とまぁ、こんな具合で動画のようなアプリを作るのにフィールド変数を1つも持たせることなく実装できます。とても凄いです・・・。
ついでにXAMLは、こんな感じです。
<Window x:Class="WpfPutRectSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Canvas Name="layoutRoot"> <Rectangle Name="dragging" Stroke="Black" Fill="Blue" Opacity="0.3"/> </Canvas> </Window>
ソースは、以下からダウンロードできます。Reactive Extensionsをインストールしてればコンパイルできると思います。
WpfPutRectSample.zip