问题
I am using a ContextMenu within a LongListSelector so that I can delete some items in the list bounded to the LLS.
I am following a recent guide here in order to implement the LLS (though I am not using the JumpList). The only thing I've changed is to have the base group class extend ObservableCollection instead of List.
The issue I am having is that once I've implemented the ContextMenu and delete from there, I can delete from the same "location" in teh visible list twice and then it would crash. Debugging shows that after the second delete, the Datacontext of the MenuItem returns the previous item that was deleted. So when I search for it in the list, the index I get is -1. I can catch this but I don't know how to then find out what was really selected as the item.
My XAML section for the contextMenu is as below:
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid toolkit:TiltEffect.IsTiltEnabled="True">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu x:Name="conmen" Loaded="ContextMenu_Loaded">
<toolkit:MenuItem Header="Delete" Click="DeleteItem_Click"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Background="{StaticResource PhoneInverseBackgroundBrush}" Padding="{StaticResource PhoneTouchTargetOverhang}">
<TextBlock Text="{Binding Usr, StringFormat='x{0}'}" FontSize="32" HorizontalAlignment="Left" Width="48"/>
</Border>
<Border Grid.Column="1" Background="{StaticResource PhoneInverseBackgroundBrush}" Padding="{StaticResource PhoneTouchTargetOverhang}">
<TextBlock Text="{Binding Name}" FontSize="32" HorizontalAlignment="Left" />
</Border>
<Border Grid.Column="2" Background="{StaticResource PhoneInverseBackgroundBrush}" Padding="{StaticResource PhoneTouchTargetOverhang}">
<TextBlock Text="{Binding Type, StringFormat=\{0:C\}}" FontSize="32" HorizontalAlignment="Right" />
</Border>
</Grid>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
And this is the start of my delete_click function to remove the item:
private void DeleteItem_Click(object sender, RoutedEventArgs e)
{
var menItem = (MenuItem)sender;
editCartItem = (Model.Cartitem)menItem.DataContext;
cartIndex = editCartItem.Id;
deleteIndex = this.cartList.FindIndex(FindItem);
After two deletes, the (Model.Cartitem)menItem.DataContext returns the previously deleted item.
I have been searching for a while and have found similar cases for different frameworks and scenarios from some years before. I wanted to know if there was an updated method for doing this in WP8.
I have seen suggestions in manually re-assigning the datacontext of the ContextMenu with a Loaded or Opened event, but the DataContext still relies on a specific item in the LLS. So I can't just point it's context to the LLS's.
I've also seen that it's been pointed to as a bug with a patch here which seems exactly like my issue, but I had no idea on how to apply the patch or if it even pertained to my situation with WP8.
I've also been ensuring that the LLS's selected item is cleared and have tried re-assigning it's itemSource after each operation to no avail.
Any help or advice in the right direction would be great. I've seen some posts on here about this, but I believe I've already passed those points (such as simply getting the menuItem and using an ObservableCollection...).
回答1:
xaml:
<toolkit:ContextMenu Opened="ContextMenu_Opened">... </toolkit:ContextMenu>
c#
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;
}
you can see: Windows Phone Toolkit Context Menu Items have wrong object bound to them when an item is removed and then added
回答2:
I just came across a simular issue:
When adding items to a listbox the datacontext of the menuitem belonging to the newly added items is not set correctly.
The workaround I ended up implementing was to rebuild the listbox after adding an item:
MyListBox.ItemsSource = null;
MyListBox.Items.Clear( );
MyListBox.ItemsSource = theList;
Not sure, if would also work for your issue...
Also the performance impact for listboxes with many items should be considered.
来源:https://stackoverflow.com/questions/14084779/contextmenus-menuitem-datacontext-returns-old-items