Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows Phone Toolkit Context Menu Items have wrong object bound to them when an item is removed and then added

I just encountered a serious problem with Context Menu which I cannot resolve for hours.

To reproduce the problem I created a brand new Panorama app with the app templates for Windows Phone 8 in Visual Studio 2012. I installed Windows Phone toolkit via nugget and add context menu in the data template of the first long list selector which is bound to Items

<StackPanel Margin="0,-6,0,12">
    <TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" FontSize="{StaticResource PhoneFontSizeExtraLarge}"/>
    <toolkit:ContextMenuService.ContextMenu>
        <toolkit:ContextMenu>
            <toolkit:MenuItem Header="{Binding LineOne}" Click="MenuItem_Click_1" Tag="{Binding}">
            </toolkit:MenuItem>
        </toolkit:ContextMenu>
    </toolkit:ContextMenuService.ContextMenu>
</StackPanel>

I set the header to the LineOne property for easier debugging. I attached the following event:

private void MenuItem_Click_1(object sender, RoutedEventArgs e)
{
    var itemViewModel = (ItemViewModel)((MenuItem)sender).Tag;
    App.ViewModel.Items.Remove(itemViewModel);
    App.ViewModel.Items.Add(new ItemViewModel { LineOne = "Test", LineTwo = "Test", LineThree = "Test" });
}

I run the app and use the context menu to remove the first item. The first item disappears and a new item named Test appears at the bottom of the list as expected. If I hold this new item the menu item is bound to "runtime one" (the item that was deleted).

This was the simplest code I could get to reproduce the error but in my real app I have pretty much the same problem with more meaningful code for adding and deleting in different methods and even different pages. I had a command bound but since the databinding is wrong the command is run in the wrong view model with the wrong parameter.

Any idea why this is happening?

like image 899
Stilgar Avatar asked Dec 08 '22 17:12

Stilgar


1 Answers

For those like me not wanting to recompile toolkit here is an easy workaround based on pantaloons answer. Simpy add Opened event handler:

<toolkit:ContextMenu Opened="ContextMenu_Opened">
...
</toolkit:ContextMenu>

Event Handler code:

private void ContextMenu_Opened(object sender, RoutedEventArgs e)
{
    var menu = (ContextMenu)sender;
    var owner = (FrameworkElement)menu.Owner;
    if (owner.DataContext != menu.DataContext)
        menu.DataContext = owner.DataContext;

}
like image 155
ghord Avatar answered May 15 '23 18:05

ghord