6

We have a desktop application, in which we have a ListView, the ListView.ItemTemplate is a KPageScrollViewer which extends ScrollViewer

Although we set VirtualizingStackPanel.IsVirtualizing="True" and VirtualizingStackPanel.VirtualizationMode="Recycling"

We noticed that the constructor of KPageScrollViewer (which is within the ItemTemplate) is always executed while viewing items inside the ListView.

What we expected is that it will be created 4 to 5 times, then, the same instances will be used to view data because we are using Recycling mode, but that won't happen, thus we will end up with more and more KPageScrollViewer instances created ..

Is it because we have customized ListView.ItemsPanel ?

<ListView.ItemsPanel>
    <ItemsPanelTemplate >
        <p:KVirtualizingStackPanel IsItemsHost="True"

Any idea please? I wonder which reasons could lead to losing recycling feature?

<ListView  x:Class="KETAB.KStudio.Stage.PagesView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:p="clr-namespace:KETAB.KStudio.Stage"
    Name="PagesList" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" 
    Loaded="instScroll_Loaded"
    AllowDrop="True" 
    MouseMove="PagesList_MouseMove"
    ScrollViewer.PanningMode="None"
    VirtualizingStackPanel.IsVirtualizing="True"
    VirtualizingStackPanel.CleanUpVirtualizedItem="PagesList_CleanUpVirtualizedItem"
    VirtualizingStackPanel.VirtualizationMode="Recycling"
    >

    <ListView.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary  Source="Resources/StageResources.xaml"/>
                <ResourceDictionary Source="/KETAB.KStudio.UserControls;component/ScrollViewerStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <SolidColorBrush  x:Key="{x:Static SystemColors.HighlightBrushKey}" Opacity="0.4" Color="Transparent" />
            <SolidColorBrush  x:Key="{x:Static SystemColors.ControlBrushKey}"  Opacity="0.4" Color="Transparent"  />
            <!--<p:PageWidthConverter x:Key="PageWidthConverter" />-->
            <p:PageWidthConverter x:Key="pageWidthConverter" />
            <p:PageHeightConverter x:Key="pageHeightConverter" />
            <Style  TargetType="{x:Type ListViewItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListViewItem}">
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Setter Property="FocusVisualStyle"
            Value="{x:Null}"/>
            </Style>
        </ResourceDictionary>
    </ListView.Resources>

    <ListView.ItemTemplate>
        <DataTemplate x:Name="PagesViewDataTemplate">
            <DataTemplate.Resources>
                <Style x:Key="PageHostStyle" TargetType="{x:Type p:KPage}">
                </Style>
            </DataTemplate.Resources>
            <p:KPageScrollViewer Name="ScrollContainer" 
                                Padding="{Binding ElementName=PagesList, Path=PageScrollViewerPadding}" 
                                Height="{Binding ElementName=PagesList, Path=ScaleY, Converter={StaticResource pageHeightConverter}}"
                                Width="{Binding ElementName=PagesList, Path=ScaleX, Converter={StaticResource pageWidthConverter}}"
                                MaxHeight="{Binding ElementName=PagesList, Path=Height}"   
                                MaxWidth="{Binding ElementName=PagesList, Path=Width}"    
                                ScrollViewer.HorizontalScrollBarVisibility="{Binding ElementName=PagesList, Path=PageScrollVisibilityHori}" 
                                ScrollViewer.VerticalScrollBarVisibility="{Binding ElementName=PagesList, Path=PageScrollVisibilityVert}"                                 >
                <Grid x:Name="MarginStack" >
                    <p:KPage x:Name="KPage" SizeChanged="KPage_SizeChanged" >

                    </p:KPage>
                </Grid>
            </p:KPageScrollViewer>
        </DataTemplate>
    </ListView.ItemTemplate>

    <ListView.ItemsPanel>
        <ItemsPanelTemplate >
            <p:KVirtualizingStackPanel IsItemsHost="True"  
                                x:Name="WrapPanel1" 
                                Orientation="{Binding ElementName=PagesList, Path=MyOrientation}" 
                                VerticalAlignment="Center" 
                                HorizontalAlignment="Center"
                                ClipToBounds="{Binding ElementName=PagesList, Path=PanelClipToBounds}"           
                                Height="{Binding ElementName=PagesList, Path=ScaleY, Converter={StaticResource pageHeightConverter}}"
                                Width="{Binding ElementName=PagesList, Path=ScaleX, Converter={StaticResource pageWidthConverter}}"
                                MaxHeight="{Binding ElementName=PagesList, Path=Height}"   
                                MaxWidth="{Binding ElementName=PagesList, Path=Width}"    
                                >
            </p:KVirtualizingStackPanel>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>

</ListView>

EDIT

Here is where the ListView is used: (p:PagesView)

<Window x:Class="KETAB.KStudio.UI.WindowMain"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
    xmlns:kStudioControls="clr-namespace:KETAB.KStudio.UI"   
    xmlns:toolBoxUIPanel="clr-namespace:KETAB.KStudio.UI"   
    xmlns:Controls="clr-namespace:KETAB.KStudio.UserControls;assembly=KETAB.KStudio.UserControls"
    xmlns:p="clr-namespace:KETAB.KStudio.Stage;assembly=KETAB.KStudio.Stage"
    xmlns:tb="http://www.hardcodet.net/taskbar"
    SizeChanged="Window_SizeChanged"    
    WindowState="Maximized" 
    WindowStyle="None"
    Background="Transparent"
    ResizeMode="CanResizeWithGrip"  
    PreviewKeyUp="WindowMain_PreviewKeyUp"
    Closed="WindowMain_Closed"   
    Stylus.IsPressAndHoldEnabled="False"
    Stylus.IsTapFeedbackEnabled="False"
    Stylus.IsTouchFeedbackEnabled="False"
    Stylus.IsFlicksEnabled="False"
    AllowsTransparency="True">

    <Grid FlowDirection="LeftToRight" Name="MainUIContainer">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" MinHeight="0"   />
            <RowDefinition />
        </Grid.RowDefinitions>

        <tb:TaskbarIcon
                    x:Name="MyNotifyIcon"
                    IconSource="/KETABStudio;component/KStudioControls/KStudioIcons/Notify.ico"
                    ToolTipText="KETAB Studio" Visibility="Collapsed"/>

        <Border Name="borderContainer" ClipToBounds="True" Margin="0,0,0,0" Grid.Row="1" Grid.Column="0" BorderThickness="2, 0, 2, 2" 
                BorderBrush="{StaticResource MainWindowBorderColor}"  Background="White">
            <Grid Background="Transparent"  ClipToBounds="True" Name="MainUISplit"  SizeChanged="MainUISplit_SizeChanged">
                <!--main backgound depends on this grid-->
                <Grid.RowDefinitions>
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="auto" />
                </Grid.ColumnDefinitions>

                <Grid Background="{StaticResource background}" Margin="0" ClipToBounds="True" Name="applicationBackground">
                    <Rectangle Name="OpacityRectangle" Visibility="Hidden" Margin="0,0,-60,0" Fill="Black" ></Rectangle>                       
                </Grid>

                <!--Page Area-->
                <Grid Grid.Column="0" Grid.Row="0" Margin="0" Name="PageArea" AllowDrop="True">
                    <p:PagesView  Name="PageList" />
                    <Controls:PageLoadingControl  x:Name="pageLoadingControl"  Visibility="Collapsed"/>
                    <Controls:HelpMode x:Name="HelpModeInstance" Visibility="Collapsed"/>
                </Grid>
            </Grid>
        </Border>
    </Grid>
</Window>
vortexwolf
  • 13,967
  • 2
  • 54
  • 72
simo
  • 23,342
  • 38
  • 121
  • 218
  • Please show what your ListView is inside of – Alan Mar 17 '13 at 09:35
  • Please see EDIT above, I tried to remove un-related code to focus on the problem .. – simo Mar 17 '13 at 11:01
  • 1
    How do you scroll this ListView, if the vertical scrollbar is disabled `crollViewer.VerticalScrollBarVisibility="Hidden"`? I removed this line and virtualization started to work fine in my sample application. – vortexwolf Mar 17 '13 at 11:28
  • In your sample application, did you check if recycling is working normally? – simo Mar 17 '13 at 11:39
  • @simo I used a simple class derived from the default ScrollViewer control. I added `Debug.WriteLine` to the constructor of my custom ScrollViewer and to the `PagesList_CleanUpVirtualizedItem` handler. After 20 items constructor wasn't invoked and the cleanup event handler was invoked instead. You can download source code here https://dl.dropbox.com/u/8047386/TestScrollViewerWpf.zip and verify that in a simple case virtualization works. – vortexwolf Mar 17 '13 at 11:46
  • @vorrtex I tried your sample, its working very well, I tried to remove crollViewer.VerticalScrollBarVisibility="Hidden" at my code, but, I still don't get the expected result, no recycling .. – simo Mar 17 '13 at 13:01
  • @simo try to replace my sample by your code step by step. Then you will find out which code exactly adds this incorrect behavior. For example, if you add the customized `ListView.ItemsPanel` and the app starts to work incorrectly, then it is the main cause of the issue. – vortexwolf Mar 17 '13 at 13:47
  • We tried to remove ListView.ItemsPanel, and use the built in, still recycling is now working .. – simo Mar 17 '13 at 14:05
  • Can you try setting `ScrollViewer.CanContentScroll` to `True`? It might do the job if you are not absolutely sure that virtualization is in work. http://stackoverflow.com/questions/1924089/listbox-virtualizingstackpanel-and-smooth-scrolling-in-wpf – mostruash Mar 15 '13 at 05:02
  • Its already set to True .. – simo Mar 17 '13 at 09:30

1 Answers1

0

I read the following which may be of help...has to do with the way you're using the ItemsPanel: Virtualizing an ItemsControl? - I realize it's not exactly the same topic, but it has a good explanation about a very similar issue.

Hopefully it'll help.

Community
  • 1
  • 1
Aaj
  • 259
  • 3
  • 16