C# Windows Phone 8 ListPicker使用ContextMenu导航,但返回页面时页面完全为空

C# Windows Phone 8 ListPicker使用ContextMenu导航,但返回页面时页面完全为空,c#,windows-phone-8,contextmenu,listpicker,C#,Windows Phone 8,Contextmenu,Listpicker,我们正在使用工具箱:ListPicker控件来显示ObservableCollection。现在,我们希望用户可以选择通过ListPicker导航到ObservableCollection中对象的编辑器 我们在ItemTemplate中添加了一个ContextMenu,允许用户导航到编辑器。用户长时间点击某个项目后,将显示上下文菜单。如果用户点击菜单项,则会显示编辑器页面。用户按下编辑器中的“后退”按钮后,将返回到一个完全空白的页面-仅显示系统托盘。如果用户再次按下后退按钮,ListPicker

我们正在使用工具箱:ListPicker控件来显示ObservableCollection。现在,我们希望用户可以选择通过ListPicker导航到ObservableCollection中对象的编辑器

我们在ItemTemplate中添加了一个ContextMenu,允许用户导航到编辑器。用户长时间点击某个项目后,将显示上下文菜单。如果用户点击菜单项,则会显示编辑器页面。用户按下编辑器中的“后退”按钮后,将返回到一个完全空白的页面-仅显示系统托盘。如果用户再次按下后退按钮,ListPicker将在开始之前短暂出现,并被承载ListPicker实例的页面所替换

<toolkit:ListPicker 
    x:Name="listPicker_Generators" 
    Margin="12,-6,0,12" 
    ExpansionMode="FullScreenOnly" 
    HorizontalAlignment="Left" 
    Width="430" 
    Height="Auto" 
    VerticalAlignment="Top" 
    FullModeHeader="{Binding Source={StaticResource LocalizedStrings}, Path=LocalizedResources.label_AccountEditor_Generator}" 
    >
    <toolkit:ListPicker.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}" />
        </DataTemplate>
    </toolkit:ListPicker.ItemTemplate>
    <toolkit:ListPicker.FullModeItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Vertical">
                <TextBlock Text="{Binding Name}" FontSize="36" />
                <TextBlock Text="{Binding Notes}"  Margin="0,0,0,12" FontFamily="Segoe WP" FontSize="{StaticResource PhoneFontSizeSmall}" />
                <toolkit:ContextMenuService.ContextMenu>
                    <toolkit:ContextMenu 
                        Visibility="{Binding Visibility}"
                        Closed="ContextMenu_Closed" 
                        Opened="ContextMenu_Opened">
                        <toolkit:MenuItem 
                            Name="menuItem_Edit" 
                            Header="{Binding Source={StaticResource LocalizedStrings}, Path=LocalizedResources.label_AccountEditor_EditGenerator}" 
                            Click="menuItem_Edit_Click" />
                    </toolkit:ContextMenu>
                </toolkit:ContextMenuService.ContextMenu>
            </StackPanel>
        </DataTemplate>
    </toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
空白页的意义是什么,有没有办法去掉它?


下面是ListPicker实例的XAML

<toolkit:ListPicker 
    x:Name="listPicker_Generators" 
    Margin="12,-6,0,12" 
    ExpansionMode="FullScreenOnly" 
    HorizontalAlignment="Left" 
    Width="430" 
    Height="Auto" 
    VerticalAlignment="Top" 
    FullModeHeader="{Binding Source={StaticResource LocalizedStrings}, Path=LocalizedResources.label_AccountEditor_Generator}" 
    >
    <toolkit:ListPicker.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}" />
        </DataTemplate>
    </toolkit:ListPicker.ItemTemplate>
    <toolkit:ListPicker.FullModeItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Vertical">
                <TextBlock Text="{Binding Name}" FontSize="36" />
                <TextBlock Text="{Binding Notes}"  Margin="0,0,0,12" FontFamily="Segoe WP" FontSize="{StaticResource PhoneFontSizeSmall}" />
                <toolkit:ContextMenuService.ContextMenu>
                    <toolkit:ContextMenu 
                        Visibility="{Binding Visibility}"
                        Closed="ContextMenu_Closed" 
                        Opened="ContextMenu_Opened">
                        <toolkit:MenuItem 
                            Name="menuItem_Edit" 
                            Header="{Binding Source={StaticResource LocalizedStrings}, Path=LocalizedResources.label_AccountEditor_EditGenerator}" 
                            Click="menuItem_Edit_Click" />
                    </toolkit:ContextMenu>
                </toolkit:ContextMenuService.ContextMenu>
            </StackPanel>
        </DataTemplate>
    </toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>


下面是上下文菜单处理的代码

    private void menuItem_Edit_Click(object sender, RoutedEventArgs e)
    {
        AccountViewModel.GeneratorChoice item = ((AccountViewModel.GeneratorChoice)((sender as FrameworkElement).DataContext));

        if (item != null)
        {
            AccountViewModel vm = DataContext as AccountViewModel;
            vm.HoldingSelectedGeneratorIndex = listPicker_Generators.SelectedIndex;

            NavigationService.Navigate(new Uri("/Views/GeneratorEditor.xaml?id=" + item.Id.ToString(), UriKind.Relative));

            // force the selection to change so we get redrawn when we come back
            if (listPicker_Generators.SelectedIndex > 0)
                listPicker_Generators.SelectedIndex--;
            else
                listPicker_Generators.SelectedIndex++;
        }
    }

    private void ContextMenu_Closed(object sender, RoutedEventArgs e)
    {
        AccountViewModel vm = DataContext as AccountViewModel;
        vm.ContextMenuOpen = false;
    }

    private void ContextMenu_Opened(object sender, RoutedEventArgs e)
    {
        // a work-around from http://stackoverflow.com/questions/15181441/windows-phone-toolkit-context-menu-items-have-wrong-object-bound-to-them-when-an
        ContextMenu contextMenu = (sender as ContextMenu);

        FrameworkElement owner = (contextMenu.Owner as FrameworkElement);
        if (owner.DataContext != contextMenu.DataContext)
            contextMenu.DataContext = owner.DataContext;

        AccountViewModel.GeneratorChoice item = contextMenu.DataContext as AccountViewModel.GeneratorChoice;

        if (item.Id.Value != 0)
        {
            bool factorySupplied = item.FactorySupplied == null ? false : true;

            if (factorySupplied)
            {
                contextMenu.Items.OfType<MenuItem>().First(m => (string)m.Name == "menuItem_Edit").Header = AppResources.label_AccountEditor_ViewGenerator;
            }

            AccountViewModel vm = DataContext as AccountViewModel;
            vm.ContextMenuOpen = true;
        }
    }
private void menuItem\u Edit\u单击(对象发送方,路由目标)
{
AccountViewModel.GeneratorChoice项=((AccountViewModel.GeneratorChoice)((发送方作为FrameworkElement.DataContext));
如果(项!=null)
{
AccountViewModel vm=DataContext作为AccountViewModel;
vm.holdingselectedgenerator索引=列表选择器\u Generators.SelectedIndex;
NavigationService.Navigate(新Uri(“/Views/GeneratorEditor.xaml?id=“+item.id.ToString(),UriKind.Relative));
//强制更改选择,以便在返回时重新绘制
如果(listPicker\u Generators.SelectedIndex>0)
listPicker_Generators.SelectedIndex--;
其他的
listPicker_生成器。选择了索引++;
}
}
私有void上下文菜单_关闭(对象发送方,路由目标e)
{
AccountViewModel vm=DataContext作为AccountViewModel;
vm.ContextMenuOpen=false;
}
私有无效上下文菜单打开(对象发送方,路由目标)
{
//一个从http://stackoverflow.com/questions/15181441/windows-phone-toolkit-context-menu-items-have-wrong-object-bound-to-them-when-an
ContextMenu ContextMenu=(发送方作为ContextMenu);
FrameworkElement所有者=(contextMenu.owner作为FrameworkElement);
if(owner.DataContext!=contextMenu.DataContext)
contextMenu.DataContext=owner.DataContext;
AccountViewModel.GeneratorChoice项=contextMenu.DataContext作为AccountViewModel.GeneratorChoice;
如果(item.Id.Value!=0)
{
bool factorySupplied=item.factorySupplied==null?false:true;
如果(工厂提供)
{
contextMenu.Items.OfType().First(m=>(string)m.Name==“menuItem\u Edit”).Header=AppResources.label\u AccountEditor\u ViewGenerator;
}
AccountViewModel vm=DataContext作为AccountViewModel;
vm.ContextMenuOpen=true;
}
}

如果不需要导航回listpicker的全屏,只需覆盖details页面上的back键,然后导航回承载listpicker的页面

详情页:

protected override void OnBackKeyPress(CancelEventArgs e)
{
    base.OnBackKeyPress(e);
    e.Cancel = true;
    NavigationService.Navigate(
        new Uri("ListPickerView.xaml", UriKind.Relative));
}
}

编辑

恐怕使用listpicker是不可能的。因此,您必须编写一个单独的页面来模拟listpicker全屏模式。如果检查工具箱中的控件,您会注意到它在内部导航到ListPickerPage.xaml页面。该页的状态保存和DataContext分配由控件完成


在“详细信息”页面上,当您按下“硬件后退”按钮时,框架会弹出位于导航历史堆栈顶部的页面,即ListPickerPage.xaml。此时,页面没有传递数据上下文,这就是为什么您会看到空白页面。

谢谢@Pantelis。我们希望编辑器返回到ListPicker的全屏,从而为用户提供编辑/查看其他项目的机会,而不是返回到承载ListPicker的页面。建议的用户体验可能有些尴尬。感谢对ListPickerPage.xaml的分析,@Pantelis。为什么ListPickerPage.xaml不保留状态以便重新建立DataContext。这听起来像个虫子。很遗憾,因为当你点击控件时,状态被提供给ListPickerPage。点击后,您将导航到一个单独的页面。如果您知道平台上的导航系统,则会发生正常行为。正如我提到的,按back键,弹出并将历史堆栈的顶部页面加载到框架中。该控件还被设计为替代其他框架中的组合框,即单项选择。因此,您想要实现的功能可能无法通过认证。