user490524
user490524

Reputation:

Windows Phone Panorama + Data Binding Issues

I'd like to have every letter of the alphabet as a single Windows Phone PanoramaItem. Please just accept it at this point. Every letter is displayed in several ways (italic, regular, bold, other fonts...). Of course I could do it manually, but it's unflexible. So I decided to write a simple Letter class, which basically holds two characters - uppercase and lowercase of a letter. The idea was to bind a collection of those Letters to the Panorama (myPano.ItemsSource=collection;). Here's the template:

<DataTemplate 
        x:Name="LetterTemplate">
        <controls:PanoramaItem

            Background="Black"
            HorizontalAlignment="Stretch"
            Name="{Binding Path=UpperCase}"
            ManipulationCompleted="A_ManipulationCompleted"
            >
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="0.5*"/>
                <RowDefinition Height="0.5*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.5*"/>
                <ColumnDefinition Width="0.5*"/>
            </Grid.ColumnDefinitions>
            <StackPanel
                Grid.Row="0"
                Grid.Column="0"
                Orientation="Vertical"
                HorizontalAlignment="Stretch">
                <TextBlock
                    Text="{Binding Path=UpperCase}"
                    Foreground="{StaticResource PhoneAccentBrush}"
                    HorizontalAlignment="Center"
                    FontFamily="Segoe WP"
                    FontSize="100" />
                <TextBlock
                    Text="{Binding Path=UpperCase}"
                    HorizontalAlignment="Center"
                    Foreground="White"
                    FontFamily="Courier New"
                    FontSize="100" />
            </StackPanel>
            <StackPanel
                Grid.Row="0"
                Grid.Column="1"
                Orientation="Vertical"
                HorizontalAlignment="Stretch">
                <TextBlock
                    Text="{Binding Path=UpperCase}"
                    Foreground="White"
                    HorizontalAlignment="Center"
                    FontFamily="Segoe WP"
                    FontStyle="Italic"
                    FontSize="100" />
                <TextBlock
                    Text="{Binding Path=UpperCase}"
                    HorizontalAlignment="Center"
                    Foreground="{StaticResource PhoneAccentBrush}"
                    FontStyle="Italic"
                    FontFamily="Courier New"
                    FontSize="100" />
            </StackPanel>
                <StackPanel
                Grid.Row="1"
                Grid.Column="0"
                Orientation="Vertical"
                HorizontalAlignment="Stretch">
                    <TextBlock
                    Text="{Binding Path=LowerCase}"
                    Foreground="{StaticResource PhoneAccentBrush}"
                    HorizontalAlignment="Center"
                    FontFamily="Segoe WP"
                    FontStyle="Italic"
                    FontSize="100" />
                    <TextBlock
                    Text="{Binding Path=LowerCase}"
                    HorizontalAlignment="Center"
                    Foreground="White"
                    FontStyle="Italic"
                    FontFamily="Courier New"
                    FontSize="100" />
                </StackPanel>
                <StackPanel
                Grid.Row="1"
                Grid.Column="1"
                Orientation="Vertical"
                HorizontalAlignment="Stretch">
                    <TextBlock
                    Text="{Binding Path=LowerCase}"
                    Foreground="White"
                    HorizontalAlignment="Center"
                    FontFamily="Segoe WP"
                    FontStyle="Italic"
                    FontSize="100" />
                    <TextBlock
                    Text="{Binding Path=LowerCase}"
                    HorizontalAlignment="Center"
                    Foreground="{StaticResource PhoneAccentBrush}"
                    FontStyle="Italic"
                    FontFamily="Courier New"
                    FontSize="100" />
                </StackPanel>
            </Grid>
    </controls:PanoramaItem>

I know it's not very performance-oriented when programming for Windows Phone, but let's leave it that way for now.

The Panorama was filled with a simple loop in the constructor of the phone page, iterating from character code 'A' to 'Z', creating the appropriate letter and adding it to the alphabet collection. It worked nicely, but was kind of slow: I had to wait for ~3 seconds until it was displayed, which is unacceptable.

My first solution of this issue was to limit the alphabet collection to 5 Letters and edit 4 of them when the selection changes. I tried several approaches, but basically my problem is to update the PanoramaItems when the modification happened.

Remove and add Letters from the collection: Destroys the nice transitions, no way. Make the collection fire CollectionChanged when a property of a contained Letter changes: Tried it, same as before. UpdateTarget() of BindingExpression: The method seems to be unavailable in .NET CE.

Maybe I overlooked something or just followed totally unsuitable approaches. How would you do it?

Thanks in advance!

Upvotes: 0

Views: 1042

Answers (4)

user490524
user490524

Reputation:

Thanks for the replies!

@decyclone: Odd, I didn't see yours... Anyhow, maybe I'll give it a shot. I just wonder how different it is to my solution with the collection. I implemented the NotifyPropertyChanged stuff in Letter and fired it, but the PanoramaItem didn't update automagically. Why should it do that now?

@MartinHN: I know it's not the best solution when speaking of performance. That's what I said in the first entry and the reason why I asked here :)

Upvotes: 0

MartinHN
MartinHN

Reputation: 19772

Keep in mind that 26 PanoramaItems might slow the performance down.

Looking at the first bullet point in the Best Practices section here, it says:

Ensure panoramic applications perform smoothly by limiting the number of sections used to a maximum of four sections. If your content is dense, or if many of your sections share multiple hosted controls, then you should use even fewer sections.

Upvotes: 1

decyclone
decyclone

Reputation: 30830

If you use the following class structure:

class LetterContainer
{
    public Letter Letter { get; set; }
}

class Letter
{
    public String UpperCase { get; set; }
    public String LowerCase { get; set; }
}

And instead of creating a list of class Letter, create a list of type LetterContainer to bind with Parorama control. Of course you will need to change bindings in your Template that you have created. Now, all you do is change values of Letter property in LetterContainer objects. This way, no CollectionChanged events will be fired. But, make sure you raise PropertyChanged events for Letter, UpperCase and LowerCase properties.

Upvotes: 0

user490524
user490524

Reputation:

For completeness' sake: I left it the first way (26 PanoramaItems) now, just removed the StackPanels in my DataTemplate and changed the ObservableCollection to a List. According to this tips & tricks entry I therefore should have gained a small performance boost. It's okay.

Still... If you know a solution to my specific problem of updating a single PanoramaItem (Target of Binding) on Windows Phone, please let me know.

Kind regards.

Upvotes: 0

Related Questions