在尝试在我的应用程序中实现Drag& Drop时,我遇到了一些奇怪的行为。我使用HierarchicalDataTemplate
在TreeView
中表示我的数据结构,如此:
XAML:
<TreeView Name="treeViewNotes" AllowDrop="True" PreviewMouseLeftButtonDown="treeViewNotes_PreviewMouseLeftButtonDown" PreviewMouseMove="treeViewNotes_PreviewMouseMove" Drop="treeViewNotes_Drop" DragEnter="treeViewNotes_DragEnter" SelectedItemChanged="treeViewNotes_SelectedItemChanged">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:NoteCategory}" ItemsSource="{Binding Notes}">
<StackPanel Orientation="Horizontal">
<Image Height="16" Source="{Binding TreeViewIcon}" Tag="{Binding Self}"/>
<Label Content="{Binding Title}" Tag="{Binding Self}" Margin="3"/>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:TextNote}">
<StackPanel Orientation="Horizontal">
<Image Height="16" Source="{Binding TreeViewIcon}" Tag="{Binding Self}"/>
<Label Content="{Binding Title}" Tag="{Binding Self}" Margin="3"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
CODE:
private void buttonCreateNote_Click(object sender, RoutedEventArgs e)
{
ObservableCollection<NoteCategory> NoteCategoriesList = new ObservableCollection<NoteCategory>();
NoteCategory category1 = new NoteCategory("Category 1", Properties.Resources.FolderIcon);
TextNote textNote1 = new TextNote("Text note 1", Properties.Resources.TextNoteIcon, category1, "Blah blah. Content for note 1");
TextNote textNote2 = new TextNote("Text note 2", Properties.Resources.TextNoteIcon, category1, "Blah blah. Content for note 2");
NoteCategory category2 = new NoteCategory("Category 2", Properties.Resources.FolderIcon);
TextNote textNote4 = new TextNote("Text note 4", Properties.Resources.TextNoteIcon, category2, "Blah blah. Content for note 4");
TextNote textNote5 = new TextNote("Text note 5", Properties.Resources.TextNoteIcon, category2, "Blah blah. Content for note 5");
NoteCategoriesList.Add(category1);
NoteCategoriesList.Add(category2);
treeViewNotes.ItemsSource = NoteCategoriesList;
}
结果:
这很好用,所以现在我希望能够在类别之间拖放音符,所以我部分地实现了here
中的代码CODE:
private void treeViewNotes_PreviewMouseMove(object sender, MouseEventArgs e)
{
Point mousePos = e.GetPosition(null);
Vector diff = Utils.DragDropStartPoint - mousePos;
if (Utils.IsDragDropping == false &&
(e.LeftButton == MouseButtonState.Pressed || e.RightButton == MouseButtonState.Pressed) &&
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
{
// Get the dragged ListViewItem
TreeView treeView = sender as TreeView;
if (e.OriginalSource is Image || e.OriginalSource is Label)
{
FrameworkElement elem = e.OriginalSource as FrameworkElement;
if (elem.Tag == null)
MessageBox.Show(elem.GetType() + "\n\nNULL");
else
MessageBox.Show(elem.GetType() + "\n\n" + elem.Tag.ToString());
}
else
MessageBox.Show(e.OriginalSource.GetType().ToString());
}
}
整个操作的关键是将Tag
绑定到TextNote
对象本身,因此当用户拖动Label
或Image
时,我可以提取它TreeViewItem
。它适用于Image
。但是,当我尝试通过单击Label
来拖动时e.OriginalSource
实际上作为带有空标记的TextBlock
来到处理程序。无论我在哪里点击并拖动鼠标,我都无法使Label
触发事件。问题是为什么?
我在TextBlock
中使用HierarchicalDataTemplate
而不是标签做了一个解决方法,但它确实有效,但我仍然很好奇为什么其他方法不起作用。