C# Windows Phone 8 ListPicker使用ContextMenu导航,但返回页面时页面完全为空
我们正在使用工具箱:ListPicker控件来显示ObservableCollection。现在,我们希望用户可以选择通过ListPicker导航到ObservableCollection中对象的编辑器 我们在ItemTemplate中添加了一个ContextMenu,允许用户导航到编辑器。用户长时间点击某个项目后,将显示上下文菜单。如果用户点击菜单项,则会显示编辑器页面。用户按下编辑器中的“后退”按钮后,将返回到一个完全空白的页面-仅显示系统托盘。如果用户再次按下后退按钮,ListPicker将在开始之前短暂出现,并被承载ListPicker实例的页面所替换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
<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键,弹出并将历史堆栈的顶部页面加载到框架中。该控件还被设计为替代其他框架中的组合框,即单项选择。因此,您想要实现的功能可能无法通过认证。