I am using a treeview in a XamOutlookBar and having some issues with it. When I have the treeview expanded and then click another group and then return to the original group the treeview is collapsed. How do I get it to maintain state?
Hello,
Could you please provide small project that reproduces this issue?
So I can investigate and try to help you.
Regards,
Anastas
I have attached a sample project. Expand the tree in group 1 and then select group 2 then go back to group 1 and the tree will be collapsed.
I wasn't able to reproduce this issue with normal TreeView. And I'm not sure why the tree in your project collapses, but I'll keep researching.
Just looking for a status on this.
The OutlookBar is like a tabcontrol in that the only content that is shown is that of the selected item. So when the first group is selected, the Content properties (e.g. Content & ContentTemplate) of the ContentPresenter within the control gets set to that first group's Content and ContentTemplate properties. Actually this is done in the templates that are then bound to the SelectedGroupContent(Template(Selector)) properties exposed on the control which are updated as the SelectedGroup changes. When that happens that ContentPresenter uses the DataTemplate from the ContentTemplate to create an instance of the element to be displayed. When you selected the 2nd group, the Content properties of that same ContentPresenter are set to the second group's Content and ContentTemplate properties. When that happens the elements created for the first group are released. When you then select the first group again, the process starts over and the ContentPresenter creates a new element from the DataTemplate you supplied for the ContentTemplate which is why you see the nodes as collapsed - because it is a different instance of a treeview. Note, this is the same exact behavior you get if you switch this to a tab control. e.g.
<TabControl HorizontalAlignment="Left" Width="250" ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, Path=NavigationMenuItems}" ScrollViewer.CanContentScroll="True"> <TabControl.Resources> <DataTemplate x:Key="ItemTemplate"> <TreeView Margin="0" BorderThickness="0" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" Background="#767676" ItemsSource="{Binding}"> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding NavigationMenuItemChildren}"> <StackPanel Orientation="Horizontal" ToolTip="{Binding ToolTip}"> <TextBlock Text="{Binding Header}"/> </StackPanel> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView> </DataTemplate> <Style TargetType="{x:Type TabItem}"> <Setter Property="Content" Value="{Binding NavigationMenuItems}"/> <Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}"/> <Setter Property="Header" Value="{Binding Path=Header}"/> <Setter Property="ToolTip" Value="{Binding Path=ToolTip}"/> </Style> </TabControl.Resources></TabControl>
<Style TargetType="{x:Type TabItem}"> <Setter Property="Content" Value="{Binding NavigationMenuItems}"/> <Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}"/> <Setter Property="Header" Value="{Binding Path=Header}"/> <Setter Property="ToolTip" Value="{Binding Path=ToolTip}"/> </Style> </TabControl.Resources></TabControl>
So what options do I have. Is there anyway to save the state of the Content just before it gets refreshed?
There is no simple answer. You could try to save some state on your viewmodel objects so that you can bind things like the IsExpanded so that that state is restored when the new tree is created. Or you could create elements (e.g. the group and set its content) for items in your itemssource.
Got this figured out! Actually is was very simple, I added a IsExpanded property to the object the TreeViewItem was binding to. Then just bind it to the IsExpanded property of the TreeViewItem. Make sure it is a TwoWay binding and all is good.