WPFやSilverlightの表示は、XAMLで作成されているので、うまくやれば Windows アプリケーションの図形移動よりも楽に移動ができる…ハズです。
Windows コントロールの場合は、ボタンなどのような標準コントロールの場合はドラッグ&ドロップのイベントが用意されているのですが、四角や文字などを移動しようと思うと途端に難しくなります。
# マウスイベントを拾って移動すればいいだけなのですが、まあ、
# 面倒と言えば面倒。図形のサイズを変えようとすると、ひと苦労だし。
WPFやSilverlightのビューは、XAMLで書かれているので、ここの値を直接書き変えてやれば、移動や回転などができます。ボタン以外も、矩形や円なども同様に移動などができるわけです。
で、実際にやってみたのですが、結果を言えば、やっぱり「ひと苦労」ですね。
矩形のハンドル(四隅にある四角)を使って大きさなどを変えようと思うと、ハンドル自身のマウスダウンイベントや、移動のイベントなどを拾う必要があります。
さて、具体的な例は、もう少しソースを整理してから紹介することにして。
実は WPF と Silverlight には、あらかじめドラッグできるコントロールが用意されています。これが、「Thumbコントロール」なのです。リストボックスなどのスクロールバーに使われています。
Thumb クラス
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.primitives.thumb.aspx
で、結論を先に言うと、これを使って汎用的なドラッグできるコントロールができるかというと、「できません!」。あくまで、スクロールバーなどに使うコントロールで、一般的な形になっていません。なので、色やら枠線やらが固定になっています。
ま、ひとつ、参考までにソースを晒しておきます。
■WPFの場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | < Window x:Class = "SampleThumb.Window1" xmlns = http ://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x = http ://schemas.microsoft.com/winfx/2006/xaml Title = "Window1" Height = "300" Width = "400" > < Canvas > < TextBlock Canvas.Left = "0" Canvas.Top = "0" Height = "22" Name = "textPos" Width = "75" Text = "x:0 y:0" /> < Rectangle Canvas.Left = "46" Canvas.Top = "48" Height = "70" Name = "rectangle1" Stroke = "Black" Width = "109" Fill = "pink" /> < Thumb Canvas.Left = "141" Canvas.Top = "103" Height = "30" Name = "mark" Width = "30" Background = "LightBlue" DragCompleted = "mark_DragCompleted" DragStarted = "mark_DragStarted" DragDelta = "mark_DragDelta" /> </ Canvas > </ Window > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | namespace SampleThumb { /// <summary> /// Window1.xaml の相互作用ロジック /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void printPos( UIElement el) { int x = ( int )Canvas.GetLeft( el ); int y = ( int )Canvas.GetTop( el ); textPos.Text = string .Format( "x:{0} y:{1}" , x, y); } /// <summary> /// ドラッグ開始 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mark_DragStarted( object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e) { mark.Background = Brushes.Pink; Debug.Print( "start" ); } /// <summary> /// ドラッグ終了 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mark_DragCompleted( object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e) { mark.Background = Brushes.LightBlue; Debug.Print( "end" ); } /// <summary> /// ドラッグ中 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mark_DragDelta( object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { printPos(mark); Canvas.SetLeft(mark, Canvas.GetLeft(mark) + e.HorizontalChange); Canvas.SetTop(mark, Canvas.GetTop(mark) + e.VerticalChange); } } } |
肝は、Thumb コントロールの3つのイベントです。
・DragStartedイベント
・DragCompletedイベント
・DragDeltaイベント
ドラッグ中は、DragDeltaイベント内で、mark(移動するThumbコントロール)の位置を変更します。位置は、canvas を使って簡便に、SetLeft、SetTop メソッドを使っています。
■Silverlightの場合
まったく同じものが Silverlight でも動作します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | < UserControl x:Class = "SampleThumbSilverlight.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = http ://schemas.microsoft.com/winfx/2006/xaml xmlns:d = "<a href=" http://schemas.microsoft.com/expression/blend/2008">http://schemas.microsoft.com/expression/blend/2008</ a >" xmlns:mc="< a href = "http://schemas.openxmlformats.org/markup-compatibility/2006" >http://schemas.openxmlformats.org/markup-compatibility/2006</ a >" mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="300"> < Canvas x:Name = "LayoutRoot" > < TextBlock Canvas.Left = "0" Canvas.Top = "0" Height = "22" Name = "textPos" Width = "75" Text = "x:0 y:0" /> < Rectangle Canvas.Left = "46" Canvas.Top = "48" Height = "70" Name = "rectangle1" Stroke = "Black" Width = "109" Fill = "pink" /> < Thumb Canvas.Left = "141" Canvas.Top = "103" Height = "30" Name = "mark" Width = "30" Background = "LightBlue" DragCompleted = "mark_DragCompleted" DragStarted = "mark_DragStarted" DragDelta = "mark_DragDelta" /> </ Canvas > </ UserControl > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | namespace SampleThumbSilverlight { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void printPos(UIElement el) { int x = ( int )Canvas.GetLeft(el); int y = ( int )Canvas.GetTop(el); textPos.Text = string .Format( "x:{0} y:{1}" , x, y); } /// <summary> /// ドラッグ開始 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mark_DragStarted( object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e) { mark.Background = new SolidColorBrush(Colors.Orange); } /// <summary> /// ドラッグ終了 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mark_DragCompleted( object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e) { mark.Background = new SolidColorBrush(Colors.Purple); } /// <summary> /// ドラッグ中 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mark_DragDelta( object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { printPos(mark); Canvas.SetLeft(mark, Canvas.GetLeft(mark) + e.HorizontalChange); Canvas.SetTop(mark, Canvas.GetTop(mark) + e.VerticalChange); } } } |
Siverlight の動作はこちらで確認できます。
http://www.moonmile.net/sl/SampleThumb/
という訳で、Thumbコントロールは汎用的ではないので「使えない」。
仕方がないので、MouseLeftButtonDown イベントなどを地道に取得することになります。
~~ 2010/04/01 追記 ~~
「使えない」と思っていたのですが、Template 化して使うことができました。
となると、自前でドラッグフラグを作らなくていいから、Thumb コントロールは使えるのでは?
すみません、
>あくまで、スクロールバーなどに使うコントロールで、一般的な形になっていません。なので、色やら枠線やらが固定になっています。
これってどういう意味ですか?
他のコントロール同様、TemplateにEllipseなりTextBoxなり適当に詰め込んでみたら
ちゃんとドラッガブルになりましたが…
Canvasの外に持っていけないって事をおっしゃってます?
おお、なるほど!Templateにするといけますね。これはやっていませんでした。
ありがとうございます。
実は「できない」と思っていたから、矩形の大きさを変えるハンドル(四隅の小さな四角)を自作していたんですよね。あと、矢印を動的に配置するツール。う~ん、これだと、ハンドル部分を Thumb の Template を変更するほうが、手早いのかも。試してみます。