Getting the SelectedItem of a ListBox Inside Dynamic Pivot

Feb 17, 2012 at 8:56 AM

Hello everyone,

I know it's a long title, but I hope it won't discourage you from coming in and giving me some hand :)

I have a view which consists of Pivot control (I'm talking Windows Phone by the way) that is populated (or maybe constructed) dynamically. Each of the Pivot control item has its own ListBox.

In the view there is also one Button which when clicked a message box is displayed with the value of the selected item of the ListBox of the currently active PivotItem... I hope that wasn't too much to comprehend :)

Appreciate any help.

Essam

Feb 21, 2012 at 1:51 AM

No one? :(

Coordinator
Feb 21, 2012 at 2:17 AM

Here's something that might help:

public class PivotViewModel : Conductor<PivotItemViewModel>.Collection.OneActive{
   public PivotViewModel(){
      //add items to collection
   }

   public void SomeAction(){
      var nameOfSelection = ActiveItem.ActiveItem.DisplayName;
   }
}

public class PivotItemViewModel : Conductor<ListItemViewModel>.Collection.OneActive{
}
In Xaml, the pivot is bound to the first conductor. The view for the pivot items is bound to the second conductor.

Feb 21, 2012 at 12:54 PM

Thanks Rob.

Let me try to get my head around this :)

Currently I have only one view and it's as simple as:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="72"/>
    </Grid.RowDefinitions>

    <controls:Pivot x:Name="Brands" Title="Huh!" Grid.Row="0">
        <controls:Pivot.HeaderTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}"/>
            </DataTemplate>
        </controls:Pivot.HeaderTemplate>
        <controls:Pivot.ItemTemplate>
            <DataTemplate>
                <ListBox ItemsSource="{Binding Products}"/>
            </DataTemplate>
        </controls:Pivot.ItemTemplate>
    </controls:Pivot>
    <Button x:Name="DoAction" Content="Okay" Width="192" VerticalAlignment="Center" Grid.Row="1"/>
</Grid>

and my ViewModel is even simpler:

public class MainPageViewModel
{
    public Brand[] Brands
    {
        get { return (new BrandsListing()).Brands; }
    }

    public void DoAction()
    {
        System.Windows.MessageBox.Show("Someone clicked me!");
    }
}

This gives me the "magic" of populating the Pivot items and the ListBox items (each Brand has Products wich returns Product[] obviously).

Based onyour example, I need to create two new ViewModels, 'BrandViewModel' and 'ProductViewModel' so that I have:

public class MainPageViewModel : Conductor<BrandsViewModel>.Collection.OneActive {}

public class BrandsViewModel : Conductor<ProductsViewModel>.Collection.OneActive {}

Is that right? And then what? What should they do? What about Views? Do I need any?

I tried registering and instance of 'BrandsListing' and inject it in each of the ViewModels but it didn't work :|

Yeah, too many questions I know; I'm still getting my head around this magic :)

Essam

Coordinator
Feb 21, 2012 at 7:35 PM

Ultimately, you need to databind the Pivot's SelectedItem to a property on your VM and you need to bind your ListBox's SelectedItem as well. That woud allow you to get at the information in your view model. There are several ways to do that. Some involve using additional VMs like I showed. You might be able to add the property directly to your MainPageViewModel for the ListBox binding and just bind down into it using ElementName and Path bindings.

Feb 24, 2012 at 6:43 AM

Am I missing something obvious here? If getting the SelectedItem of a ListBox inside a dynamic Pivot requires some "hard work", then let me first focus on the Pivot SelectedItem... I'm unable to get that as well! :|

I went back to the simple app I started with and added the following property to my MainPageViewModel:

private Brand brandX;
public Brand BrandX
{
    get { return brandX; }
    set
    {
        if (brandX == value) { return; }

        brandX = value;
        NotifyOfPropertyChange(() => BrandX);
    }
}

And then bound my Pivot SelectedItem to BrandX in my MainPageView:

<controls:Pivot x:Name="Brands" Title="Huh!" SelectedItem="{Binding BrandX}" Grid.Row="0">

Now when I click the button in the page it tells me that "BrandX is null".

Here is my app source. Have a look if it's not too much to ask :)

Essam