0
votes

Back in the old days with Windows Phone 7, I've managed to program a very long code to generate a UI from code-behind imitating some kind of a WrapPanel, showing the hour on the left and list all the minutes (for departure data) on the right. When 8 entries has been added, it created a new line.

The structure of it looked something like this:

  • StackPanel (Vertical): Contains all the rows for different hours
  • StackPanel (Horizontal):
    • TextBlock: Hour
    • StackPanel (Vertical): Contains horizontal StackPanels, each storing 8 TextBlocks with minutes in them

Result example:

08  05 10 15 20 25 30 35 40
    45 50 55
09  10 20 30 40 50

With Windows Phone 8.1 I thought I shall use a GridView with grouping instead of updating the previous code. This way I could use all the mighty powers of the bindings. However it takes about 2-3 seconds for the GridView to render about 180-200 TextBlocks which is kinda disappointing.

<CollectionViewSource x:Name="DepartureData" Source="{Binding DepartureData}" IsSourceGrouped="True" ItemsPath="Entries" />

<GridView x:Name="listTimetable"
          ItemsSource="{Binding Source={StaticResource DepartureData}}"
          Grid.Column="1">
    <GridView.GroupStyle>
        <GroupStyle HidesIfEmpty="True">
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding FormattedHour}" 
                               Foreground="Black" FontSize="20" FontWeight="Bold"
                               HorizontalAlignment="Center"
                               Margin="0,0,15,0" />
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
        </GroupStyle>
    </GridView.GroupStyle>
    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsWrapGrid GroupHeaderPlacement="Left" Orientation="Horizontal" ItemHeight="40" ItemWidth="34" />
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>
    <GridView.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding FormattedMinute}"
                       Style="{StaticResource TimetableDataActive}" />
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

Generating the UI from code-behind would result in a far better performance, but it would definetly make it much more difficult to maintain the code. What might be the reason of the huge difference in time between the GridView and the code-behind solution? Maybe the binding itself slows the rendering process down, or the plus amount of ContentPresenters, Borders, and etc that comes with the GridViewItems?

1

1 Answers

1
votes

Okay the last sentence just came in my mind when I was writing this question and it seems it have answered it.

GridViewItem's style contains many many - sometimes unnecessary - elements. Borders, placeholders, select boxes, etc. You can check them at: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj709915.aspx

When you have a big amount of data that you wish to show most likely without interacting it, it is highly advised to reduce the amount of UI data in these GridViewItems. The following code shows an example for this:

<GridView.ItemContainerStyle>
    <Style TargetType="GridViewItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <ContentPresenter x:Name="contentPresenter"
                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                  Margin="{TemplateBinding Padding}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</GridView.ItemContainerStyle>
<GridView.ItemTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding FormattedMinute}"
                   Style="{StaticResource TimetableDataActive}" />
    </DataTemplate>
</GridView.ItemTemplate>

The style has been reduced to the ContentPresenter only - you will need to have it, because this will present the content defined in the template - and the same template has been used. This way the UI renders within half a second. I hope I could help out some of you folks with this example!