На самом деле все оказалось довольно логично: Дело в том, что ItemsSource.ItemContainerGenerator.ItemFromContainer производит поиск в своих элементах. Он не знает, что может содержать элементы, также производные от ItemsControl (как TreeViewItem). Поэтому для решения задачи нужно вызывать ItemContainerGenerator.ItemFromContainer у родительского элемента первого уровня.
private void treeView1_PreviewMouseMove(object sender, MouseEventArgs e)
{
Point mousePos = e.GetPosition(null);
Vector diff = _DragStart - mousePos;
if (e.LeftButton == MouseButtonState.Pressed &&
Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance &&
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
TreeView treeView = sender as TreeView;
TreeViewItem treeViewItem =
FindAnchestor<TreeViewItem>((DependencyObject)e.OriginalSource);
if (treeViewItem != null)
{
// ищем родительский элемент
ItemsControl parent = FindParent<ItemsControl>(treeViewItem);
object item = parent.ItemContainerGenerator.
ItemFromContainer(treeViewItem);
if (item is Measure)
{
DataObject dragData = new DataObject("Measure", item);
DragDrop.DoDragDrop(treeViewItem, dragData, DragDropEffects.Move);
}
}
}
И еще один хелпер
private static T FindParent<T>(FrameworkElement current)
where T : FrameworkElement
{
do
{
current = VisualTreeHelper.GetParent(current) as FrameworkElement;
if (current is T)
{
return (T)current;
}
}
while (current != null);
return null;
}