Note that there are some explanatory texts on larger screens.

plurals
  1. POData binding to a TreeView using HierarchicalDataTemplate
    primarykey
    data
    text
    <p>I'm trying to get the TreeView control in my application to properly bind to a tree of objects by setting its <code>ItemsSource</code> and <code>DataContext</code> properties. The tree visualizes as expected, but the <code>TreeViewItem</code>s data context seems to hold incorrect values.</p> <p>For example, I have a tree that looks like this:</p> <pre><code>[-] Header [-] Contents [+] Item1 [+] Item2 properties [+] Dictionary [-] MetaDictionary [+] TypeDef1 [+] TypeDef2 properties </code></pre> <p>The items are bound to the objects' <code>Data.Name</code> value. However, if I click any item that is a child of <code>Header</code> and examine it in the event handler, its <code>DataContext.Data.Name</code> says <code>Header</code> (after appropriate castings). Same thing happens with <code>MetaDictionary</code> and its children.</p> <p>This is a shortened version of my class: </p> <pre><code> public class CFItemTreeNode { private CFItem data; public CFItem Data { get { return data; } set { data = value; } } private ObservableCollection&lt;CFItemTreeNode&gt; children; public ObservableCollection&lt;CFItemTreeNode&gt; Children { //set &amp; get as above } private CFItemTreeNode parent; public CFItemTreeNode Parent { //set &amp; get as above } } </code></pre> <p>And this is my XAML. I've been scouring SO and the net for several days and I've incorporated bits and pieces of various tutorials and questions into this Frankenstein of mine. I believe it's a problem with the hierarchical template, but that's as far as I've gotten. </p> <pre><code>&lt;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"&gt; &lt;Window.Resources&gt; &lt;Style x:Key="TreeViewItemStyle" TargetType="{x:Type TreeViewItem}"&gt; &lt;!-- A margin of 0 px left and 2 px top --&gt; &lt;Setter Property="Margin" Value="0 2" /&gt; &lt;Setter Property="AllowDrop" Value="true" /&gt; &lt;EventSetter Event="TreeViewItem.PreviewMouseLeftButtonDown" Handler="TVI_PreviewMouseLeftButtonDown" /&gt; &lt;EventSetter Event="TreeViewItem.PreviewMouseMove" Handler="TVI_PreviewMouseMove" /&gt; &lt;EventSetter Event="TreeViewItem.PreviewDrop" Handler="TVI_PreviewDrop" /&gt; &lt;/Style&gt; &lt;/Window.Resources&gt; &lt;Grid&gt; &lt;Grid.RowDefinitions&gt; &lt;RowDefinition Height="25" /&gt; &lt;RowDefinition Height="575*" /&gt; &lt;/Grid.RowDefinitions&gt; &lt;Grid.ColumnDefinitions&gt; &lt;ColumnDefinition Width="390*" /&gt; &lt;ColumnDefinition Width="390*" /&gt; &lt;/Grid.ColumnDefinitions&gt; &lt;ToolBar Name="menuBar" Grid.ColumnSpan="2" ToolBarTray.IsLocked="True"&gt; &lt;Button Name="buttonOpen" Click="OpenFile"&gt;Open file&lt;/Button&gt; &lt;/ToolBar&gt; &lt;TreeView Grid.Row="1" Grid.Column="0" Name="treeView" ItemContainerStyle="{StaticResource TreeViewItemStyle}" ItemsSource="{Binding}"&gt; &lt;TreeView.Resources&gt; &lt;HierarchicalDataTemplate DataType="{x:Type local:CFItemTreeNode}" ItemsSource="{Binding Children}"&gt; &lt;Grid&gt; &lt;TextBlock Text="{Binding Path=Data.Name}" MouseLeftButtonDown="TBlock_PreviewMouseLeftButtonDown"/&gt; &lt;TextBox Text="{Binding Path=Data.Name, Mode=TwoWay}" Visibility="Collapsed" LostFocus="TBox_LostFocus"/&gt; &lt;/Grid&gt; &lt;/HierarchicalDataTemplate&gt; &lt;/TreeView.Resources&gt; &lt;/TreeView&gt; &lt;TextBox Grid.Row="1" Grid.Column="1" Name="textOutput" /&gt; &lt;/Grid&gt; &lt;/Window&gt; </code></pre> <p>What am I doing wrong?</p> <p><strong>Update 1.</strong> Here are my event handlers: </p> <pre><code>private void TVI_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs args) { dragStartPosition = args.GetPosition(null); dragSource = args.OriginalSource; } </code></pre> <pre class="lang-cs prettyprint-override"><code>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 &amp;&amp; dragStartPosition.X != -1 &amp;&amp; args.LeftButton == MouseButtonState.Pressed &amp;&amp; Math.Pow(currentPosition.X - dragStartPosition.X, 2) + Math.Pow(currentPosition.Y - dragStartPosition.Y, 2) &gt; 25) { dragInProgress = true; DragDropEffects de = DragDrop.DoDragDrop( (TreeViewItem)sender, new DataObject(typeof(FrameworkElement), dragSource), DragDropEffects.Move); } } </code></pre> <pre class="lang-cs prettyprint-override"><code>private void TVI_PreviewDrop(object sender, DragEventArgs args) { if (dragInProgress &amp;&amp; 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 &lt; 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); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload