C# 在HierarchycalDataTemplate中,标签转换为TextBlock
在尝试在我的应用程序中实现拖放时,我遇到了一些奇怪的行为。我正在使用C# 在HierarchycalDataTemplate中,标签转换为TextBlock,c#,wpf,xaml,binding,C#,Wpf,Xaml,Binding,在尝试在我的应用程序中实现拖放时,我遇到了一些奇怪的行为。我正在使用hierarchycaldatatemplate在TreeView中表示我的数据结构,如下所示: XAML: 整个操作的关键是将标记绑定到文本注释对象本身,因此当用户拖动树项的标签或图像时,我可以提取它。它适用于图像。但是,当我试图通过单击标签来拖动时,e.OriginalSource实际上作为带有空标记的TextBlock到达处理程序。无论在何处单击并拖动鼠标,我都无法使标签触发事件。问题是为什么? 我通过使用TextBloc
hierarchycaldatatemplate
在TreeView
中表示我的数据结构,如下所示:
XAML:
整个操作的关键是将标记
绑定到文本注释
对象本身,因此当用户拖动树项
的标签或图像
时,我可以提取它。它适用于图像
。但是,当我试图通过单击标签来拖动时,e.OriginalSource
实际上作为带有空标记的TextBlock
到达处理程序。无论在何处单击并拖动鼠标,我都无法使标签
触发事件。问题是为什么?
我通过使用TextBlock
而不是hierarchycaldatatemplate
中的标签来解决问题,它可以工作,但是我仍然很好奇为什么另一种方法不起作用。你可以通过将e.OriginalSource
转换为FrameworkElement
并使用它的DataContext
+1来简单地提取整个TextNote
对象,我想补充一点,这种行为并不奇怪,但确实是它应该做的。标签是由TextBlock组成的,这就是为什么WPF告诉您正在拖动这样的元素。如果您真的想检查元素,只需使用VisualTreeHelper:Thank@MarioVernari沿着视觉层次结构走一走即可。标签
的结构可能包含一个文本框
。
<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>
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;
}
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());
}
}