1
votes

I finally got my pivot control to work using MVVM in a wp8 app but I still have a question in regards to binding as thought as it works, and I could accept it as is, I'm not happy with the outcome and I'm trying to understand why this is happening. My DataContext, MainViewModel, contains multiple other ViewModels.

Scenario 1:

If I define the DataContext in the Grid (layout), and I assign the itemsSource for the pivot headers to QuickSearchTabs ViewModel and this get built ok but the listbox I have defined inside the pivotitem doesn't which is assigned the QuickSearchButtons ViewModel doesn't get built. Here is the xaml code:

<Grid x:Name="LayoutRoot" Background="Transparent" DataContext="{StaticResource MainViewModel}" >
    <phone:Pivot x:Name="Pivot" ItemsSource="{Binding QuickSearchTabs}" FontSize="{StaticResource PhoneFontSizeSmall}" SelectedIndex="{Binding SelectedSearchTabIndex, Mode=TwoWay}">
        <phone:Pivot.Title>
            <TextBlock Text="My Search Options" />
        </phone:Pivot.Title>
        <phone:Pivot.HeaderTemplate>
            <DataTemplate>
                <ContentControl Content="{Binding Name}" />
            </DataTemplate>
        </phone:Pivot.HeaderTemplate>
        <phone:Pivot.ItemTemplate>
            <DataTemplate>
                <ListBox ItemsSource="{Binding QuickSearchButtons}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition></RowDefinition>
                                    <RowDefinition></RowDefinition>
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"></ColumnDefinition>
                                </Grid.ColumnDefinitions>
                                <Button Content="{Binding Name}" Grid.Row="0">
                                </Button>
                                <TextBlock Text="{Binding Description}"  Grid.Row="1">
                                </TextBlock>
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </DataTemplate>
        </phone:Pivot.ItemTemplate>
    </phone:Pivot>
</Grid>

Scenario 2:

If I define the DataContext in the Grid (layout) and define the same DataContext within the listbox tags, it will build my header and my listbox BUT it will call my viewModel which is assigned to the ItemsSource of the listbox, multiple times. To be exact, it will call it the same number of time as the number of pivots I have. Here is the xaml code:

<Grid x:Name="LayoutRoot" Background="Transparent" DataContext="{StaticResource CriteriaViewModel}" >
    <phone:Pivot x:Name="Pivot" ItemsSource="{Binding QuickSearchTabs}" SelectedIndex="{Binding SelectedSearchTabIndex, Mode=TwoWay}" >
        <phone:Pivot.Title>
            <TextBlock Text="My Search Options" />
        </phone:Pivot.Title>
        <phone:Pivot.HeaderTemplate>
            <DataTemplate>
                <ContentControl Content="{Binding Name}"/>
            </DataTemplate>
        </phone:Pivot.HeaderTemplate>
        <phone:Pivot.ItemTemplate>
            <DataTemplate>
                <ListBox ItemsSource="{Binding QuickSearchButtons}" DataContext="{StaticResource CriteriaViewModel}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition></RowDefinition>
                                    <RowDefinition></RowDefinition>
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"></ColumnDefinition>
                                </Grid.ColumnDefinitions>
                                <Button Content="{Binding Name}" Grid.Row="0">
                                </Button>
                                <TextBlock Text="{Binding Description}"  Grid.Row="1">
                                </TextBlock>
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </DataTemplate>
        </phone:Pivot.ItemTemplate>
    </phone:Pivot>
</Grid>

As mentioned, this works, and it's not affecting me in anyway as the correct data is always displayed.

I can somehow see what's happening but why on earth would the ItemsSource be set for each of the defined pivot headers. Surely, the only important one is the one coming into visibility!

I don't know if Pivots are suppose to be used the way I'm using them. It seems, from what I've seen so far that normally a view is assigned to each PivotItem. This is not how I want my solution to work!

I just want numerous headers which are used to groups things in a specific manner and whatever is displayed under each is build dynamically but on the same view i.e. list of buttons and label.

Any ideas on how I could get scenario 1) to work and if I'm stuck with scenario 2, how to stop it from being triggered based on the number of pivot header items?

Thanks.

1

1 Answers

1
votes

Problem solved!

The QuickSearchTabs was an observable collection of QuickSearchTab when it should have been an observable collection of ViewModel i.e. QuickSearchTabViewModel and within this viewModel, it will load the observable collection of relevant QuickSearchButtons for each of the tab.

Having a QuickSearchTabViewModel provides more flexibility and it will allow access to the current tab (header), and other relevant properties including everything maintain within each of these tabs such as, in my case the buttons.

Hope this helps.