Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ContextMenu in DataTemplate Binding issue

I have a context menu in LongListSelector. This list is created and updated in runtime.

<phone:PanoramaItem Header="{Binding Path=LocalizedResources.SavedGamesHeader, Source={StaticResource LocalizedStrings}}" Orientation="Horizontal">
            <phone:LongListSelector Margin="0,0,-22,2" ItemsSource="{Binding SavedGames}">
                <phone:LongListSelector.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical" Margin="12,2,0,20" Width="432">
                            <toolkit:ContextMenuService.ContextMenu>
                                <toolkit:ContextMenu>
                                    <toolkit:MenuItem Header="Remove" Click="RemoveSave_OnClick"/>
                                </toolkit:ContextMenu>
                            </toolkit:ContextMenuService.ContextMenu>
                            <Image Margin="10,5,10,0"  Height="173" Width="248" Source="{Binding Screen}" Stretch="Fill" HorizontalAlignment="Left"></Image>
                            <StackPanel Width="311" Margin="8,5,0,0" HorizontalAlignment="Left">
                                <TextBlock Tap="Save_OnTap" Tag="{Binding SavedGame}" Text="{Binding SaveName}" TextWrapping="Wrap" Margin="10,0" Style="{StaticResource PhoneTextExtraLargeStyle}" FontSize="{StaticResource PhoneFontSizeMedium}" Foreground="White" FontWeight="Bold" FontFamily="Arial Black" HorizontalAlignment="Left" />
                                <TextBlock Text="{Binding GameName}" TextWrapping="Wrap" Margin="10,-2,10,0" Style="{StaticResource PhoneTextSubtleStyle}" HorizontalAlignment="Left" />
                                <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                                    <TextBlock Text="Created on:" Margin="10,-2,10,0" Style="{StaticResource PhoneTextSubtleStyle}" />
                                    <TextBlock Text="{Binding Created}" TextWrapping="Wrap" Margin="5,-2,10,0" Style="{StaticResource PhoneTextSubtleStyle}" />
                                </StackPanel>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </phone:LongListSelector.ItemTemplate>
            </phone:LongListSelector>
        </phone:PanoramaItem>

Here's the method that handles click event on menu item

private void RemoveSave_OnClick(object sender, RoutedEventArgs e)
    {
        var menuItem = (MenuItem)sender;
        var saveViewModel = menuItem.DataContext as SavesViewModel;
        EmuStorageMgr.Instance.DeleteSave(saveViewModel.SavedGame.SaveFolder);
        App.ViewModel.RescanSaves();
    }

The following method populates the SavedGames list

public ObservableCollection<SavesViewModel> SavedGames { get; private set; }
public void RescanSaves()
    {
        SavedGames.Clear();
        var saves = EmuStorageMgr.Instance.GetSaves();
        foreach (var save in saves)
        {
            SavedGames.Add(new SavesViewModel(save));
        }
        this.IsSavesLoaded = true;
        NotifyPropertyChanged("SavedGames");
    }

So, when the SavedGames collection is populaed for the first time it work perfect, but when the collections changes (delete some old items, add new) I observe some strange behaviour. When the OnClick event is fired I see menuItem.DataContext is not for the menu item I clicked but for some old menu items which were deleted.

like image 932
Shedon Avatar asked Jan 21 '13 18:01

Shedon


1 Answers

I can't leave a comment on you're post so I'll say here:

This is a known problem and one that I have also. I haven't found any way to fully resolve this issue and haven't seen any recent solutions. You can see my post hereto ensure the issue is in line with yours.

The only solution I've seen so far is described here in a msdn blog from '11. It identifies the problem in the Silverlight Framework and he provides a workaround which I implemented. Include the class file in your project and make use of the XAML tags, and it will allow your contextmenu keep in sync with the parent's datacontext. I've ran into a small side-effect using it, so it's only a band aid.

I also found tell from another forum that it's a known issue with no solution, but a patch may be found at codeplex here. My issue with the patch is I couldn't figure out how to implement it, and also the LLS (which is what I'm using the ContextMenu with) has migrated directly into the SDK, so I was stuck.

That's all I've dug up on the problem, hope it helps. If someone else has anymore to add please do.

Update: Using some of what was in the above provided links, I think I have a slightly better solution. In the ContextMenu Unloaded event, refresh the view. Something like:

    private void add_but_up(object sender, RoutedEventArgs e)
    {
        ContextMenu conmen = (sender as ContextMenu);
        conmen.ClearValue(FrameworkElement.DataContextProperty);
    }

This is essentially what the patch in the blog does. Only in a completely different context. So my issues were an inability to use functions like ScrollTo(). Doing this in the code behind of the actual page seems fix the ContextMenu binding issue.

like image 114
Poken1151 Avatar answered Sep 29 '22 20:09

Poken1151