Treeview - Hierarchical Data Template - Binding does not update on source change?

Posted by ClearsTheScreen on Stack Overflow See other posts from Stack Overflow or by ClearsTheScreen
Published on 2009-09-18T08:32:18Z Indexed on 2010/04/13 6:02 UTC
Read the original article Hit count: 800

Greetings!

I ran into this problem in my project (Silverlight 3 with C#):

I have a TreeView which is data bound to, well, a tree. This TreeView has a HierarchicalDataTamplate in a resource dictionary, that defines various controls. Now I want to hide (Visibility.Collapse) some items depending on wether a node has children or not. Other items shall be visible under the same condition.

It works like charm when I first bind the source tree to the TreeView, but when I change the source tree, the visibility in the treeview does not change.

XAML - page:

<controls:TreeView x:Name="SankeyTreeView" 
  ItemContainerStyle="{StaticResource expandedTreeViewItemStyle}"
  ItemTemplate="{StaticResource SankeyTreeTemplate}">
    <controls:TreeViewItem IsExpanded="True">
        <controls:TreeViewItem.HeaderTemplate>
            <DataTemplate>
                <TextBlock Text="This is just for loading and will be replaced directly after the data becomes available..."/>
            </DataTemplate>
        </controls:TreeViewItem.HeaderTemplate>
    </controls:TreeViewItem>
</controls:TreeView>

XAML - ResourceDictionary

<!-- Each node in the tree is structurally identical, hence only one Hierarchical
     Data Template that'll use itself on the children. -->
<Data:HierarchicalDataTemplate x:Key="SankeyTreeTemplate" 
  ItemsSource="{Binding Children}">
    <Grid Height="24">
    <TextBlock x:Name="TextBlockName" Text="{Binding Path=Value.name, Mode=TwoWay}" 
      VerticalAlignment="Center" Foreground="Black"/>
    <TextBox x:Name="TextBoxFlow" Text="{Binding Path=Value.flow, Mode=TwoWay}"
      Grid.Column="1" Visibility="{Binding Children, 
        Converter={StaticResource BoxConverter}, 
        ConverterParameter=\{box\}}"/>
    <TextBlock x:Name="TextBlockThroughput" Text="{Binding Path=Value.throughput, Mode=TwoWay}" 
      Grid.Column="1" Visibility="{Binding Children, 
        Converter={StaticResource BoxConverter}, ConverterParameter=\{block\}}"/>
    <Button x:Name="ButtonAddNode"/>
    <Button x:Name="ButtonDeleteNode"/>
    <Button x:Name="ButtonEditNode"/>
    </Grid>
</Data:HierarchicalDataTemplate>

Now, as you can see, the TextBoxFlow and the TextBlockThroughput share the same space. What I aim at: The "Throughput" value of a node is how much of something 'flows' through this node from its children. It can't be changed directly, so I want to display a text block. Only leaf nodes have a TextBox to let someone enter the 'flow' that is generated in this leaf node. (I.E.: Node.Throughput = Node.Flow + Sum(Children.Throughput), where Node.Flow = 0 for each non-leaf.)

What the BoxConverter (silly name -.-) does:

public object Convert(object value, Type targetType, object parameter,
  System.Globalization.CultureInfo culture)
{
    if ((value as NodeList<TreeItem>).Count > 1) // Node has Children?
    {
        if ((parameter as String) == "{box}")
        {
            return Visibility.Collapsed;
        }
        else ((parameter as String) == "{block}")
        {
            return Visibility.Visible;
        }
    }
    else
    {
        /*
         * As above, just with Collapsed and Visible switched
         */
    }
}

The structure of the tree that is bound to the TreeView is essentially stolen from Dan Vanderboom (a bit too much to dump the whole code here), except that I here of course use an ObservableCollection for the children and the value items implement INotifyPropertyChanged.

I would be very grateful if someone could explain to me, why inserting items into the underlying tree does not update the visibility for box and block.

Thank you in advance!

© Stack Overflow or respective owner

Related posts about silverlight-3.0

Related posts about Silverlight