MouseDragElementBehavior を使うと簡単に実装する事ができます。

MouseDragElementBehavior が無い
Visual Studio 2019 から Behavior が 標準搭載されなくなりました。
https://blog.okazuki.jp/entry/2019/03/02/221827
なので、NuGet パッケージ から入れる必要があります。
プロジェクトに「Microsoft.Xaml.Behaviors.Wpf」パッケージを入れます。

MainWindow
MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13
| <Window <!-- 省略 --> > <Grid x:Name="LayoutRoot"> <Button Content="図形追加" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Style="{StaticResource MaterialDesignRaisedButton}" Margin="10,80,0,0" Click="AddShape_Click"/> </Grid> </Window>
|
Grid コントロール にユーザーコントロールを追加するため、LayoutRoot という名前をつけました。こうする事でコードビハインドから参照することが出来ます。
MainWindow.xaml.cs
1 2 3 4
| private void AddShape_Click(object sender, RoutedEventArgs e) { LayoutRoot.Children.Add(new ShapeObject(100, 150)); }
|
図形追加ボタンを押したら、Grid コントロール ShapeObject ユーザーコントロール を追加しています。引数で追加位置を指定できるようにしています。
ShapeObject ユーザーコントロール
ShapeObject ユーザーコントロール を作っていきます。
ShapeObject.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <UserControl <!-- 省略 --> > <b:Interaction.Behaviors> <b:MouseDragElementBehavior ConstrainToParentBounds="True" X="{Binding XPosition, Mode=TwoWay}" Y="{Binding YPosition, Mode=TwoWay}"/> </b:Interaction.Behaviors> <Grid> <StackPanel> <TextBlock TextWrapping="Wrap" Text="{Binding XPosition, StringFormat=X:{0}}"/> <TextBlock TextWrapping="Wrap" Text="{Binding YPosition, StringFormat=Y:{0}}"/> </StackPanel> </Grid> </UserControl>
|
UserControl に MouseDragElementBehavior を付けています。これだけで、ドラッグ移動させることが出来ます。
ConstrainToParentBounds を True にする事で、外に出なくなります。
表示位置を表示するために、ViewModel とバインドして TextBlock で表示しています。

ShapeObject.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| using System.Windows; using System.Windows.Controls; namespace WpfApp1 { public partial class ShapeObject : UserControl { public ShapeObject(double _XPosition, double _YPosition) { InitializeComponent(); DataContext = new ShapeObjectViewModel() { XPosition = _XPosition, YPosition = _YPosition }; HorizontalAlignment = HorizontalAlignment.Left; VerticalAlignment = VerticalAlignment.Top; Width = 100; Height = 100; } } }
|
初期化してます。
ShapeObjectViewModel.cs
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
| using System.ComponentModel; using System.Runtime.CompilerServices; namespace WpfApp1 { public class ShapeObjectViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public double XPosition { get { return _XPosition; } set { if (value != _XPosition) { _XPosition = value; NotifyPropertyChanged("XPosition"); } } } private double _XPosition; public double YPosition { get { return _YPosition; } set { if (value != _YPosition) { _YPosition = value; NotifyPropertyChanged("YPosition"); } } } private double _YPosition; } }
|
ドラッグ移動で 表示位置が変わったら 通知されるようにしています。
手順が面倒くさいです。