ContextMenu的MenuItem DataContext返回旧项

时间:2012-12-29 18:39:50

标签: windows-phone-8 wpftoolkit

我在LongListSelector中使用ContextMenu,这样我就可以删除绑定到LLS的列表中的一些项目。

我正在关注最近的指南here以实现LLS(尽管我没有使用JumpList)。我唯一改变的是让基类组扩展ObservableCollection而不是List。

我遇到的问题是,一旦我实现了ContextMenu并从那里删除,我可以从可见列表中的相同“位置”删除两次然后它会崩溃。 调试显示在第二次删除后,MenuItem的Datacontext返回已删除的上一个项目。所以当我在列表中搜索它时,我得到的索引是-1。我可以抓住这个,但我不知道如何找出真正被选中的项目。

contextMenu的我的XAML部分如下:

<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>

这是我删除项目的delete_click函数的开始:

    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);

两次删除后,(Model.Cartitem)menItem.DataContext返回先前删除的项目。

我一直在寻找一段时间,并且已经找到了几年前针对不同框架和场景的类似案例。我想知道在WP8中是否有更新的方法。

我已经看到了使用Loaded或Opened事件手动重新分配ContextMenu的datacontext的建议,但DataContext仍然依赖于LLS中的特定项。所以我不能仅仅指出LLS的背景。

我也看到它被指向一个补丁here的错误,看起来与我的问题完全一样,但我不知道如何应用补丁或者它是否与我的情况有关与WP8。

我也一直在确保清除LLS的所选项目并尝试在每次操作后重新分配它的itemSource无效。

任何正确方向的帮助或建议都会很棒。我在这里看过一些关于此的帖子,但我相信我已经通过了这些点(比如简单地获取menuItem并使用ObservableCollection ......)。

2 个答案:

答案 0 :(得分:2)

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;
}

你可以看到:Windows Phone Toolkit Context Menu Items have wrong object bound to them when an item is removed and then added

答案 1 :(得分:0)

我刚遇到一个类似的问题:

将项目添加到列表框时,属于新添加项目的menuitem的datacontext未正确设置。

我最终实现的解决方法是在添加项目后重建列表框:

        MyListBox.ItemsSource = null;
        MyListBox.Items.Clear( );
        MyListBox.ItemsSource = theList;

不确定,是否也适用于您的问题...
此外,还应考虑对包含许多项目的列表框的性能影响。

相关问题