我正在尝试通过设置ItemsSource
和DataContext
属性来使我的应用程序中的TreeView控件正确绑定到对象树。树按预期可视化,但TreeViewItem
的数据上下文似乎保持不正确的值。
例如,我有一棵看起来像这样的树:
[-] Header
[-] Contents
[+] Item1
[+] Item2
properties
[+] Dictionary
[-] MetaDictionary
[+] TypeDef1
[+] TypeDef2
properties
项目绑定到对象的Data.Name
值。但是,如果我点击任何Header
子项并在事件处理程序中检查它,DataContext.Data.Name
说Header
(在适当的演员之后)。 MetaDictionary
及其子女也会发生同样的事情。
这是我班级的缩短版本:
public class CFItemTreeNode
{
private CFItem data;
public CFItem Data
{
get { return data; }
set { data = value; }
}
private ObservableCollection<CFItemTreeNode> children;
public ObservableCollection<CFItemTreeNode> Children
{
//set & get as above
}
private CFItemTreeNode parent;
public CFItemTreeNode Parent
{
//set & get as above
}
}
这是我的XAML。我已经在搜索SO和网络好几天了,我已经将各种教程和问题的各种各样的教程和问题合并到我的科学家中。我认为这是分层模板的一个问题,但就我而言。
<Window x:Class="SSLowLevelBrowser.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SSLowLevelBrowser"
Title="MainWindow"
Height="600"
Width="800"
MinHeight="100"
MinWidth="200"
Closing="MainWindowClosing">
<Window.Resources>
<Style x:Key="TreeViewItemStyle" TargetType="{x:Type TreeViewItem}">
<!-- A margin of 0 px left and 2 px top -->
<Setter Property="Margin" Value="0 2" />
<Setter Property="AllowDrop" Value="true" />
<EventSetter Event="TreeViewItem.PreviewMouseLeftButtonDown" Handler="TVI_PreviewMouseLeftButtonDown" />
<EventSetter Event="TreeViewItem.PreviewMouseMove" Handler="TVI_PreviewMouseMove" />
<EventSetter Event="TreeViewItem.PreviewDrop" Handler="TVI_PreviewDrop" />
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="575*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="390*" />
<ColumnDefinition Width="390*" />
</Grid.ColumnDefinitions>
<ToolBar Name="menuBar" Grid.ColumnSpan="2" ToolBarTray.IsLocked="True">
<Button Name="buttonOpen" Click="OpenFile">Open file</Button>
</ToolBar>
<TreeView Grid.Row="1"
Grid.Column="0"
Name="treeView"
ItemContainerStyle="{StaticResource TreeViewItemStyle}"
ItemsSource="{Binding}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:CFItemTreeNode}" ItemsSource="{Binding Children}">
<Grid>
<TextBlock Text="{Binding Path=Data.Name}"
MouseLeftButtonDown="TBlock_PreviewMouseLeftButtonDown"/>
<TextBox Text="{Binding Path=Data.Name, Mode=TwoWay}"
Visibility="Collapsed"
LostFocus="TBox_LostFocus"/>
</Grid>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
<TextBox Grid.Row="1" Grid.Column="1" Name="textOutput" />
</Grid>
</Window>
我做错了什么?
更新1。以下是我的事件处理程序:
private void TVI_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs args)
{
dragStartPosition = args.GetPosition(null);
dragSource = args.OriginalSource;
}
private void TVI_PreviewMouseMove(object sender, MouseEventArgs args)
{
Point currentPosition = args.GetPosition(null);
// If there is actual movement and a drag is starting
if (dragInProgress == false &&
dragStartPosition.X != -1 &&
args.LeftButton == MouseButtonState.Pressed &&
Math.Pow(currentPosition.X - dragStartPosition.X, 2) +
Math.Pow(currentPosition.Y - dragStartPosition.Y, 2) > 25)
{
dragInProgress = true;
DragDropEffects de = DragDrop.DoDragDrop(
(TreeViewItem)sender,
new DataObject(typeof(FrameworkElement), dragSource),
DragDropEffects.Move);
}
}
private void TVI_PreviewDrop(object sender, DragEventArgs args)
{
if (dragInProgress && args.Data.GetDataPresent(typeof(FrameworkElement)))
{
CFItemTreeNode dragSource =
((CFItemTreeNode)((FrameworkElement)args.Data.GetData(typeof(FrameworkElement))).DataContext);
CFItemTreeNode dropTarget =
((CFItemTreeNode)((FrameworkElement)args.OriginalSource).DataContext);
CFItemTreeNode sourceParent = dragSource.Parent;
CFItemTreeNode targetParent = dropTarget.Parent;
if (sourceParent != targetParent)
{
MessageBox.Show("Can only swap siblings.");
dragInProgress = false;
return;
}
int sourceIndex = sourceParent.Children.IndexOf(dragSource);
int targetIndex = sourceParent.Children.IndexOf(dropTarget);
if (sourceIndex != targetIndex)
{
if (sourceIndex < targetIndex)
{
sourceParent.Children.RemoveAt(targetIndex);
sourceParent.Children.RemoveAt(sourceIndex);
sourceParent.Children.Insert(sourceIndex, dropTarget);
sourceParent.Children.Insert(targetIndex, dragSource);
}
else
{
sourceParent.Children.RemoveAt(sourceIndex);
sourceParent.Children.RemoveAt(targetIndex);
sourceParent.Children.Insert(targetIndex, dragSource);
sourceParent.Children.Insert(sourceIndex, dropTarget);
}
}
dragSource = null;
dragInProgress = false;
// Reset start position to invalid
dragStartPosition = new Point(-1, -1);
}
}
答案 0 :(得分:0)
将RelativeSource={RelativeSource AncestorType=local:MainWindow}
添加到您的绑定中。