2

i'm trying to apply the MVVM pattern in my application with MVVM Light. I've a databinded ListBox...

MainView.xaml [extract]

<ListBox Name="recipesListBox" 
                             ItemsSource="{Binding RecipeList}"
                             SelectedItem="{Binding SelectedRecipe, Mode=TwoWay}"
                             HorizontalAlignment="Stretch"
                             VerticalAlignment="Stretch"
                             Grid.Row="1"
                             Margin="12,0,12,0"
                             SelectionChanged="recipesListBox_SelectionChanged" >

MainViewModel.cs [extract]

    private Recipe selectedRecipe;

    public Recipe SelectedRecipe
    {
        get
        {
            return selectedRecipe;
        }
        set
        {
            selectedRecipe = value;
            RaisePropertyChanged("SelectedRecipe");
        }
    }

...that performs a page navigation on SelectionChanged:

MainView.xaml.cs [extract]

private void recipesListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string destination = "/RecipeView.xaml";
            if (recipesListBox.SelectedIndex == -1) // If selected index is -1 (no selection) do nothing
                return;
            this.NavigationService.Navigate(new Uri(destination, UriKind.Relative));
            //recipesListBox.SelectedIndex = -1; // Reset selected index to -1 (no selection)
        }

After // you can see the old code that reset the index after page navigation - now, with binded data, obviously it also set null my selected item! How can i do for navigate to a new view, show the property of selected item and reset the selected index when i go back? Thank you!

maxdelia
  • 858
  • 2
  • 14
  • 35

2 Answers2

1

The best way is to have your collection stored somewhere you can access it anywhere (like in the Windows Phone Databound Application project) and pass the index of the selected item in your navigation uri

int index = recipesListBox.SelectedIndex;
this.NavigationService.Navigate(new Uri(destination +"?index="+index , UriKind.Relative));

Then in the OnNavigatedTo method of your new page get the index from the query and get the item

override OnNavigatedTo(
{
    string index;
    if(NavigationContext.QueryString.TryGetValue("index", index))
    {
        // get the item from your collection based on this index
    }

}
Shawn Kendrot
  • 12,425
  • 1
  • 25
  • 41
  • Thank you for your answer! My old code was like: Recipe selectedRecipe = recipesListBox.SelectedItem as Recipe; this.NavigationService.Navigate(new Uri(destination + "?RecipeID=" + selectedRecipe.ID, UriKind.Relative)); this.recipesListBox.SelectedIndex = -1; ...in OnNavigatedTo i retrieved the recipe through ID with a LINQ query on my xml "database" and as long as i performed actions in the method all works normally but outside the method the recipe appeared null! I obviously saved "outside" the recipe getted but it always appearing null! Regulary in OnNavigatedTo and null outside :( – maxdelia Jun 12 '12 at 18:34
  • Are you saying that the QueryString "RecipeID" is not available and is null? Is should stay in the NavigationContext. Or are you saying that the Recipe itself is null? Or that the Recipe collection is null? and in what page is it null? – Shawn Kendrot Jun 12 '12 at 19:07
  • Recipe itself becomes null! My code behind in the new view was like: private Recipe selectedRecipe; override OnNavigatedTo( { string ID; if(NavigationContext.QueryString.TryGetValue("ID", ID)) { this.selectedRecipe = GetRecipeByID(ID); }} i.e., if i try to get the Name (selectedRecipe.Name) inside OnNavigatedTo, i get exactly what i want, if i try outside i get Null*something*Exception! – maxdelia Jun 12 '12 at 20:04
1

The way I did it was this:

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
    if (listBox.SelectedItem != null)
    {
        listBox.SelectedIndex = -1;
    }

    base.OnNavigatedFrom(e);
}

then add the following to SelectionChanged event

if(SelectedItem != null)
{
    // Do something with SelectedItem
}
Jonny Lin
  • 727
  • 4
  • 11
  • Thank you for your answer! I found solution myself just yesterday, i wrote code exactly in your way! Except for if () and base.OnNavigatedFrom(e), i'm adding it right now XD Thank you again! :D – maxdelia Jun 15 '12 at 16:14