Skip to content

Instantly share code, notes, and snippets.

@pinzolo
Created June 22, 2012 06:07
Show Gist options
  • Save pinzolo/2970686 to your computer and use it in GitHub Desktop.
Save pinzolo/2970686 to your computer and use it in GitHub Desktop.
[WPF]TreeViewでのドラッグアンドドロップ
// HierarchicalDataTemplate を使用して、様々な TreeItemViewModelBase を継承したクラスを含むツリーでのドラッグアンドドロップを想定。
// typeof で実際にドラッグされたアイテムの Type を指定できないため、ホルダーを作成している。
/// <summary>
/// 最後に左クリックした座標
/// </summary>
private Point lastLeftMouseButtonDownPoint;
/// <summary>
/// ドラッグアンドドロップ開始基準となる距離
/// </summary>
private static double minimumDragDistance = 10.0;
/// <summary>
/// TreeView のマウスクリック時処理<br />
/// 左クリックの場合、ドラッグアンドドロップ判定のため座標を保存する。
/// </summary>
/// <param name="sender">発生元</param>
/// <param name="e">引数</param>
private void treeViewItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton != MouseButton.Left) { return; }
this.lastLeftMouseButtonDownPoint = e.GetPosition(this.treeView);
}
/// <summary>
/// TreeView のマウス移動時処理<br />
/// クリックされながら特定距離以上移動したらドラッグドロップを開始する。
/// </summary>
/// <param name="sender">発生元</param>
/// <param name="e">引数</param>
private void treeViewItem_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Released) { return; }
var currentPosition = e.GetPosition(this.treeView);
if (Math.Abs(currentPosition.X - this.lastLeftMouseButtonDownPoint.X) <= minimumDragDistance &&
Math.Abs(currentPosition.Y - this.lastLeftMouseButtonDownPoint.Y) <= minimumDragDistance)
{
return;
}
var holder = new TreeItemViewModelHolder(this.treeView.SelectedItem as TreeItemViewModelBase);
DragDrop.DoDragDrop(this.treeView, holder, DragDropEffects.Move);
}
/// <summary>
/// TreeView の要素にドロップされた時の処理<br />
/// 要素の配置を変更する。
/// </summary>
/// <param name="sender">発生元</param>
/// <param name="e">引数</param>
private void treeViewItem_Drop(object sender, DragEventArgs e)
{
e.Handled = true;
e.Effects = DragDropEffects.None;
var destItem = sender as TreeViewItem;
var destVM = destItem.Header as TreeItemViewModelBase;
var srcHolder = e.Data.GetData(typeof(TreeItemViewModelHolder)) as TreeItemViewModelBase;
if (srcHolder == null) { return; }
var srcVM = srcHolder.Element;
if (srcVM == destVM) { return; }
srcVM.Parent.Children.Remove(srcVM);
destVM.Children.Add(srcVM);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment