0

我试图让我的应用程序中的 TreeView 控件通过设置它的ItemsSourceDataContext属性来正确绑定到对象树。树按预期可视化,但TreeViewItems 数据上下文似乎包含不正确的值。

例如,我有一棵看起来像这样的树:

[-] Header
    [-] Contents
        [+] Item1
        [+] Item2
        properties
    [+] Dictionary
[-] MetaDictionary
    [+] TypeDef1
    [+] TypeDef2
properties

项目绑定到对象的Data.Name值。但是,如果我单击任何子项Header并在事件处理程序中检查它,它会DataContext.Data.NameHeader(在适当的强制转换之后)。同样的事情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);
    }
}
4

1 回答 1

0

添加RelativeSource={RelativeSource AncestorType=local:MainWindow}到您的绑定中。

于 2014-11-14T12:20:51.030 回答