MouseDragElementBehavior でドラッグ移動

Uncategorized
467 words

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;
}
}

ドラッグ移動で 表示位置が変わったら 通知されるようにしています。

手順が面倒くさいです。