コントロールをドラッグさせる場合、Thumbコントロールを使うのがよさそう。
Thumbコントロールは以下のようなドラッグに関するイベントを持っている。
DragStartedEvent ・・・ ドラッグが開始された時
DragCompletedEvent ・・・ ドラッグが終了した時
DragDeltaEvent ・・・ ドラッグでマウスが動いた時
Thumb自体は四角形の見た目だが、Templateを使ってカスタマイズしてしまえば色々な物が作れそう。
以下の例では、キャンバス内を自由にドラッグ移動できる画像を作ってみた。
XAML
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication1" mc:Ignorable="d" Title="MainWindow" Height="250" Width="250"> <Canvas Margin="10" Background="AliceBlue"> <Thumb Width="50" Height="50" Canvas.Left="0" Canvas.Top="0" DragStarted="Thumb_DragStarted" DragCompleted="Thumb_DragCompleted" DragDelta="Thumb_DragDelta"> <Thumb.Template> <ControlTemplate> <Border x:Name="Thumb_Border" BorderBrush="Red" BorderThickness="0"> <Image Source="testimage.jpg"/> </Border> </ControlTemplate> </Thumb.Template> </Thumb> </Canvas> </Window>
Canvasの中にThumbコントロールを作成 (10~14行目)
Thumbコントロールを配置して、DragStarted,DragCompleted,DragDeltaイベントを追加。
ControlTemplateでThumbをカスタマイズ (16~22行目)
Borderの中にImageを配置している。
ドラッグ中のみ赤枠を出すようコード側で制御する為、Borderに名前を付けている。
コード
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Thumb_DragStarted(object sender, DragStartedEventArgs e) { var thumb = sender as Thumb; if (null != thumb) { var border = thumb.Template.FindName("Thumb_Border", thumb) as Border; if (null != border) { border.BorderThickness = new Thickness(1); } } } private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e) { var thumb = sender as Thumb; if (null != thumb) { var border = thumb.Template.FindName("Thumb_Border", thumb) as Border; if (null != border) { border.BorderThickness = new Thickness(0); } } } private void Thumb_DragDelta(object sender, DragDeltaEventArgs e) { var thumb = sender as Thumb; if (null != thumb) { var x = Canvas.GetLeft(thumb) + e.HorizontalChange; var y = Canvas.GetTop(thumb) + e.VerticalChange; var canvas = thumb.Parent as Canvas; if (null != canvas) { x = Math.Max(x, 0); y = Math.Max(y, 0); x = Math.Min(x, canvas.ActualWidth - thumb.ActualWidth); y = Math.Min(y, canvas.ActualHeight - thumb.ActualHeight); } Canvas.SetLeft(thumb, x); Canvas.SetTop(thumb, y); } } }
DragStartedイベント (8~19行目)
ドラッグ中のみBorderで赤枠を出すように制御している。
"Thumb_Border"という名前でTemplateの中を検索してBorderコントロールを取得。
BorderTicknessを1にして枠を表示している。
DragCompletedイベント (21~32行目)
ドラッグ中のみBorderで赤枠を出すように制御している。
"Thumb_Border"という名前でTemplateの中を検索してBorderコントロールを取得。
BorderTicknessを0にして枠を非表示にしている。
DragDeltaイベント (34~54行目)
DragDeltaEventArgsのHorizontalChange,VerticalChangeにドラッグの移動量が入っているので、
それを使ってThumbの位置を移動させている。
また、親要素のCanvasを取得して、Canvasの外に出ないように移動後の座標を制御している。
(42~49行目)
コメントをお書きください