0

ItemsSourceプロパティとプロパティを設定して、アプリケーションの TreeView コントロールをオブジェクトのツリーに適切にバインドしようとしていますDataContext。ツリーは期待どおりに視覚化されますが、TreeViewItems データ コンテキストは正しくない値を保持しているようです。

たとえば、次のようなツリーがあります。

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

Data.Name項目はオブジェクトの値にバインドされます。ただし、の子であるアイテムをクリックしてHeaderイベントハンドラーで調べると、(適切なキャストの後) と表示されます。とその子でも同じことが起こります。DataContext.Data.NameHeaderMetaDictionary

これは私のクラスの短縮版です:

    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 に答える