概要

  • DragMove*1の動作をさせたいControlに対して、添付ビヘイビアを書くだけで動作を実現する

コード全体

	/// <summary>
	/// ドラッグムーブを実現する添付ビヘイビア
	/// </summary>
	public static class DragMoveBehaviour {
		public static bool GetCanDragMove(UIElement elem) {
			return (bool)elem.GetValue(CanDragMoveProperty);
		}

		public static void SetCanDragMove(UIElement elem, bool val) {
			elem.SetValue(CanDragMoveProperty, val);
		}

		public static readonly DependencyProperty CanDragMoveProperty =
			DependencyProperty.RegisterAttached(
				"CanDragMove",
				typeof(bool),
				typeof(DragMoveBehaviour),
				new PropertyMetadata(OnPropertyChanged));

		private static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
			//Propertyが変更されたときにMouseDownのイベントハンドラを登録しておく

			var target = sender as UIElement;
			if (target == null) return;
			if ((bool)e.NewValue == true) {
				target.MouseDown += OnMouseDown;
			} else {
				//do nothing
			}
		}

		private static void OnMouseDown(object sender, MouseButtonEventArgs e) {
			//押されたオブジェクトが所属するWindowを探してDragMove()する

			var obj = sender as DependencyObject;
			if (obj == null) return;
			if (e.ChangedButton == MouseButton.Left && e.LeftButton == MouseButtonState.Pressed) {
				getParentWindow(obj).DragMove();
			}
		}

		private static Window getParentWindow(DependencyObject current) {
			//引数currentを内部に持っているwinを探して返す
			foreach (Window win in App.Current.Windows) {
				if (win.IsAncestorOf(current)) {
					return win;
				}
			}
			throw new InvalidOperationException("Couldn't find window");
		}
	
<Border util:DragMoveBehaviour.CanDragMove="True"
上記のようにBorderに添付ビヘイビアを付けたことによって、Borderをクリックしたままドラッグすると、Windowがドラッグに従って移動する

コードの解説(添付ビヘイビア初心者用)

  • GetCanDragMove、SetCanDragMove、CanDragMovePropertyはおきまりといっていい作法
(propaと入力するスニペットで出てくる)
  • 上記で、"CanDragMove"というbool型のプロパティを定義している。このプロパティを変更するとOnPropertyChangedが呼び出される
  • DependencyProperty.RegisterAttachedを使うことで添付プロパティにしている。単なる依存関係プロパティのときはDependencyProperty.Register()
  • OnPropertyChangedイベントの引数を利用して添付したオブジェクトが得られるので、それにイベントを仕込む
使い方の例ようにBorderに添付すると、senderにBorderが入っているので、Borderにイベントを追加する

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

どなたでも編集できます