views:

91

answers:

2

I'm trying the MVVM Light Toolkit. Though I still think having multiple ViewModels for such small apps is overkill, I like the concepts. What I still can't quite understand is how (or I should say "what is the recommended way") to navigate from one page to another when the selection changes in a ListBox.

The big problem with this toolkit is that it forces you to learn MVVM via other sources before using it, rather than show you what (its vision of) MVVM is from within the framework, accompanying samples and documentation. Are there samples out there showing the different concepts? And please, no videos.

A: 

Have you tried modifying your ListBox ItemTemplate to have each item be a HyperlinkButton and just setting the NavigateURI attribute to the Page you want to navigate to?

Matt Casto
Hmmm, the web thinking, I'm not used to this. So you would recommend each ListBoxItem to contain an HyperlinkButton (obviously templated not to look like a link) with an URI containing a query parameter referring to the ID of the selected item? Others agree that this is the way to do it on Windows Phone 7?By the way, being new to Silverlight, I feel stupid not seeing anything when I put a Grid and bound child controls inside the button. What am I missing?
Martin Plante
You've got two questions there, and the second one is begging for its own question with more details. As far as the HyperlinkButton, Yes, that's what I would try. HyperlinkButton controls styled to look like other things are very powerful. For instance, its easy to create a tab strip with HyperlinkButton controls inside a horizontal StackPanel.
Matt Casto
A: 

I still have not figured out how to do this (navigate to a details page upon selection changed in a listbox) without any codebehind in the view. However, if you are OK with having just a little codebehind in the view here's what I recommend:

<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}"
    SelectionChanged="MainListBox_SelectionChanged" 
    SelectedItem="{Binding Path=SelectedListItem, Mode=TwoWay}">
    <ListBox.ItemTemplate>
         <DataTemplate>
              <StackPanel Margin="0,0,0,17" Width="432">
                  <TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
                  <TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
              </StackPanel>
        </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

First, per above bind to the SelectedItem property of the Listbox with a TwoWay binding to a property in your ViewModel (SelectedListItem in the above).

Then in your codebehind for this page implement the handler for MainListBox_SelectionChanged:

    // Handle selection changed on ListBox
    private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        // If selected index is -1 (no selection) do nothing
        if (MainListBox.SelectedIndex == -1)
            return;

        // Navigate to the new page
        NavigationService.Navigate(new Uri("/DetailsPage.xaml", UriKind.Relative));

    }

This is the only codebehind you need in your main view.

In your main ViewModel you need a SelectedListItem property:

    public const string SelectedListItemPropertyName = "SelectedListItem";
    private ItemViewModel _SelectedListItem;
    /// <summary>
    /// Sample ViewModel property; this property is used in the view to display its value using a Binding
    /// </summary>
    /// <returns></returns>
    public ItemViewModel SelectedListItem
    {
        get
        {
            return _SelectedListItem;
        }
        set
        {
            if (value != _SelectedListItem)
            {
                _SelectedListItem = value;
                RaisePropertyChanged(SelectedListItemPropertyName);
            }
        }
    }

Now, the trick to getting the context passed to your details page (the context being what list item was selected) you need to setup the DataContext in your Details view:

public DetailsPage()
{
    InitializeComponent();
    if (DataContext == null)
        DataContext = App.ViewModel.SelectedListItem;

}

Hope this helps.

cek