マウスダウン、マウス移動、マウスアップを含むドラッグアンドドロップ操作を処理しようとしています。
これが私のソリューションの簡略化された再現です。
- マウスを下に向けると、楕円が作成され、キャンバスに追加されます
- マウスを動かすと、楕円がマウスに追従するように再配置されます
マウスを上にすると、キャンバスの色が変更され、ドラッグしているキャンバスが明確になります。
var mouseDown = Observable.FromEvent<MouseButtonEventArgs>(canvas, "MouseLeftButtonDown"); var mouseUp = Observable.FromEvent<MouseButtonEventArgs>(canvas, "MouseLeftButtonUp"); var mouseMove = Observable.FromEvent<MouseEventArgs>(canvas, "MouseMove"); Ellipse ellipse = null; var q = from start in mouseDown.Do(x => { // handle mousedown by creating a red ellipse, // adding it to the canvas at the right position ellipse = new Ellipse() { Width = 10, Height = 10, Fill = Brushes.Red }; Point position = x.EventArgs.GetPosition(canvas); Canvas.SetLeft(ellipse, position.X); Canvas.SetTop(ellipse, position.Y); canvas.Children.Add(ellipse); }) from delta in mouseMove.Until(mouseUp.Do(x => { // handle mouse up by making the ellipse green ellipse.Fill = Brushes.Green; })) select delta; q.Subscribe(x => { // handle mouse move by repositioning ellipse Point position = x.EventArgs.GetPosition(canvas); Canvas.SetLeft(ellipse, position.X); Canvas.SetTop(ellipse, position.Y); });
XAMLは単純です
<Canvas x:Name="canvas"/>
このコードについて私が気に入らないことがいくつかあり、リファクタリングの助けが必要です:)
まず第一に、mousedownとmouseupのコールバックが副作用として指定されています。に2つのサブスクリプションが作成された場合q
、それらは2回発生します。
次に、mousemoveコールバックの前にmouseupコールバックが指定されます。これにより、読みにくくなります。
第三に、楕円への参照はばかげた場所にあるようです。サブスクリプションが2つある場合、その変数参照はすぐに上書きされます。キーワードを活用してlinq式に変数を導入する方法があるはずです。これはlet
、マウス移動ハンドラーとマウスアップハンドラーの両方で正しい楕円参照を使用できることを意味します。
このコードをどのように書きますか?