DataBound Pivot control is not creating the first

2019-01-27 13:36发布

问题:

In a Windows Phone 7 page I have the following control:

<controls:Pivot x:Name="Pivoter" Title="{Binding Name}" 
      TitleTemplate="{StaticResource PivotTitleTemplate}" 
      HeaderTemplate="{StaticResource PivotHeaderTemplate}"
      ItemsSource="{Binding Items}"
      ItemTemplate="{StaticResource DisplayItemDataTemplate}">
</controls:Pivot >

with this DataTemplate:

<DataTemplate x:Key="DisplayItemDataTemplate">    
    <Image Grid.Column="0" Stretch="Uniform"
        Source="{Binding LargeImage, Converter={StaticResource UriBitmapConverter}}"/>
    <StackPanel Grid.Column="1" Orientation="Vertical">
        <HyperlinkButton NavigateUri="{Binding Uri}" Content="{Binding Uri}"/>
    </StackPanel>    
</DataTemplate>

The ItemsSource is an ObservableCollection. When the page is displayed it creates all of the PivotItems but the first item does not get created unless I scroll forward and back to it. It has an entry in the scroll list but no PivotItem control.

If I put a break point in the Pivot Control's LoadingPivotItem event it is not called when the pivot is first displayed but again only gets hit when I scroll away and back to the first item.

Has anybody seen similar behavior for the Pivot control and have a work around? Or am I doing something incorrectly?

回答1:

I ran into this same problem.

It appears the DataContext for the pivot should be set in the constructor. I was setting my DataContext in the Page_Loaded event and the first pivot item would not fire the Loading event, as described. By simply binding my DataContext earlier, the event started firing.

I believe it's a bug in the framework, but I haven't done enough to confirm it.



回答2:

I ran in to this, and I couldn't solve this by setting the data-context in the constructor, as the data that was going to displayed was depending on information from the NavigationService, so I had to load the data in the page_loaded-event handler.

But by setting the pivot-controls SelectedIndex to 1 in the page-loaded-event, it magically started working. Its not an ideal solution, but in this case, it was a blocker that I just had to fix.

Sample code:

void ChannelOverview_Loaded(object sender, RoutedEventArgs e)
    {
        string channelSystemName;
        if(this.NavigationContext.QueryString.TryGetValue("channelSystemName", out channelSystemName))
        {
            this.viewModel.LoadData(this.Dispatcher, channelSystemName);
            //Set the SelectedIndex to one,
            //otherwise the pivot-view won't render the first item.
            this.overviewPivot.SelectedIndex = 1;
        }
        else 
        {
            MessageBox.Show("Kanalen hade ett felaktigt Id ");
        }
    }


回答3:

Might be a bit late, but will might help somebody. As documented, SelectedIndex of the pivot if 0 and a data context change resulting in SelectedIndex being 0 again does not update the first pivot item and neither calls pivot item loading event. However, following also worked when i had a data bound pivot control. Note that pivotTypes.Items[ 0 ] returns the data bound object and not the pivot item.

pivotTypes.SelectedItem = pivotTypes.Items[ 0 ];


回答4:

This blogpost solved my problem.

My issue with the other offered solutions was that I wasn't able to use the constructor to set the DataContext and that, at times, there was just one PivotItem so I could switch back and forth to load the content.

The solution is extremely simple: before updating the collection that the Pivot is bound to set its DataContext to null. Then update the collection and after that set the DataContext to the collection.