TreeView state lost when resizing outlookbar

May 23, 2011 at 5:00 AM

I am having a problem with a TreeView in the OutlookBar control. Whenever I resize the outlookbar, it seems to reload my treeview and all the state is lost so if the user has expanded a few levels and selected an item, then resizes the control, their selection will be lost. Any idea why this would be happening?

Thanks

        <odc:OutlookBar Header="Tools" Grid.Row="0" IsCloseButtonVisible="False" IsButtonSplitterVisible="False" IsOverflowVisible="False"
                    IsPopupVisible="False" ShowSideButtons="True" ShowButtons="True" Name="outlookBar">
            <odc:OutlookBar.Sections>
                <odc:OutlookSection Header="Tree">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        <TextBlock Grid.Row="0" Text="Edit data." TextWrapping="Wrap"/>
                        <TreeView Grid.Row="1" ItemsSource="{Binding Path=Items}" DisplayMemberPath="Name"
                                               mvvm:RoutedEventCommand.RoutedEventName="MouseDoubleClick" mvvm:RoutedEventCommand.CommandBinding="{Binding Path=LoadSelectedItemCommand}" FontSize="10">
                            <TreeView.Resources>
                                <Style TargetType="{x:Type TreeViewItem}">
                                    <Setter Property="ItemsSource" Value="{Binding Path=Children}"/>
                                    <Setter Property="IsSelected" Value="{Binding Path=IsSelected}"/>
                                </Style>
                            </TreeView.Resources>
                        </TreeView>
                    </Grid>
                </odc:OutlookSection>
            </odc:OutlookBar.Sections>
        </odc:OutlookBar>

May 24, 2011 at 3:28 AM

Well, I think I have found a clue. It seems that whenever the outlookbar is resized it is causing the itemssource on my treeview to be reevaluated (A breakpoint on the getter is hit immediately when resizing the outlookbar). Does anyone know why my binding would be getting reset when the control is resized?

Jun 5, 2011 at 6:11 AM

I think I found how to fix this problem. It seems that the ApplySections code is recreating all the sections of the control every time the size is changed. I modified the function to only update the sections if the number of maximized or minimized sections changes. Here is my new function:

    /// <summary>
    /// Determine the collection of MinimizedSections and MaximizedSections depending on the MaxVisibleButtons Property.
    /// </summary>
    protected virtual void ApplySections()
    {
        if (this.IsInitialized)
        {
            Collection<OutlookSection> newMaximizedSections = new Collection<OutlookSection>();
            Collection<OutlookSection> newMinimizedSections = new Collection<OutlookSection>();
            int max = MaxNumberOfButtons;
            int index = 0;
            int selectedIndex = SelectedSectionIndex;
            OutlookSection selectedContent = null;

            int n = GetNumberOfMinimizedButtons();

            foreach (OutlookSection e in sections)
            {
                e.OutlookBar = this;
                e.Height = ButtonHeight;
                if (max-- > 0)
                {
                    e.IsMaximized = true;
                    newMaximizedSections.Add(e);
                }
                else
                {
                    e.IsMaximized = false;
                    if (newMinimizedSections.Count < n)
                    {
                        newMinimizedSections.Add(e);
                    }
                }
                bool selected = index++ == selectedIndex;
                e.IsSelected = selected;
                if (selected) selectedContent = e;
            }

            if (maximizedSections == null ||
                minimizedSections == null ||
                newMaximizedSections.Count != maximizedSections.Count ||
                newMinimizedSections.Count != minimizedSections.Count)
            {
                maximizedSections = newMaximizedSections;
                minimizedSections = newMinimizedSections;
                SetValue(OutlookBar.MaximizedSectionsPropertyKey, newMaximizedSections);
                SetValue(OutlookBar.MinimizedSectionsPropertyKey, newMinimizedSections);
            }
            SelectedSection = selectedContent;
        }
    }