在导航到新页面时运行代码:
this.Frame.Navigate(typeof(BlankPage1), pages);
当代码连接到BlankPage1.xaml.cs中的以下代码时,代码运行正常并产生正确的输出
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_thumbnails = e.Parameter as ObservableCollection<ThumbnailImage>;
FileView.ItemsSource = _thumbnails;
}
但是,当我运行
CoreApplicationView newView = CoreApplication.CreateNewView();
int newViewId = 0;
await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Frame frame = new Frame();
frame.MinHeight = 800;
frame.MaxWidth = 400;
frame.MinWidth = 200;
frame.Navigate(typeof(BlankPage1), pages);
Window.Current.Content = frame;
Window.Current.Activate();
newViewId = ApplicationView.GetForCurrentView().Id;
});
bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
要创建一个新的View并导航到相同的xaml文件,它将引发异常:“抛出异常:Viewer.exe中的'System.Exception''”
但是,当OnNavigatedTo更改为
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_thumbnails = e.Parameter as ObservableCollection<ThumbnailImage>;
//FileView.ItemsSource = _thumbnails;
}
没有错误,但未填充GridView。
班级是
public class ThumbnailImage
{
public BitmapImage Source { get; set; }
public StorageFile File { get; set; }
public ThumbnailImage(BitmapImage source, StorageFile file)
{
Source = source;
File = file;
}
}
xaml是
<Page Width="300" Height="850"
x:Class="Viewer.BlankPage1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Viewer"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<GridView x:Name="FileView" Width="256" Height="850" Margin="0,20,0,0">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:ThumbnailImage">
<Grid>
<Button FontFamily="Segoe MDL2 Assets" Content="" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Image CanDrag="True" Stretch="Uniform" Source="{x:Bind Source}" Height="100" Margin="10,40"/>
<Border Opacity=".8" Background="Black" VerticalAlignment="Bottom"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal" ScrollViewer.VerticalScrollBarVisibility="Visible"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
</ScrollViewer>
</Page>
答案 0 :(得分:1)
不建议在UWP中的两个不同视图之间传递ObservableCollection
(或任何其他基于INotifyPropertyChanged
-或INotifyCollectionChanged
的模型),不推荐。
原因是UWP中的每个视图都有其自己的UI线程,这也是您需要使用新创建的视图的Dispatcher
导航到页面的原因。但是,当您使用数据绑定时,对集合的任何更改都将执行CollectionChanged
,这将针对两个应用视图运行。这将不可避免地导致应用崩溃,因为CollectionChanged
和PropertyChanged
影响UI,因此必须在特定视图的UI线程上运行-在这种情况下,每个视图都有自己的UI线程。
因此,为确保避免出现这些问题,请创建一个新集合,以确保每个视图都有自己的ObservableCollection
实例:
var secondaryViewPages = new ObservableCollection<ThumbnailImage>(pages);
frame.Navigate(typeof(BlankPage1), secondaryViewPages);
注意:如果ThumbnailImage
实现了INotifyPropertyChanged
,则还必须为集合中的每个图像创建一个“副本”。但是,在这种情况下,ThumbnailImage
是POCO是没有必要的,并且不会将其更改通知UI。
也请注意::不建议将集合用作参数Navigate
,因为它会阻止您在应用暂停期间序列化应用状态,请参见docs:
应用通常在应用暂停时使用GetNavigationState序列化框架的状态。您可以直接在应用程序代码中执行此操作,也可以使用Visual Studio模板生成的SuspensionManager类间接执行此操作。要使用GetNavigationState启用帧状态序列化,必须仅对导航参数使用基本类型,例如字符串,字符,数字和GUID类型。否则,当应用程序挂起时,GetNavigationState将引发异常。如果不使用GetNavigationState,则参数可以具有其他类型。
相反,您可以以不同的方式在视图之间共享数据,例如拥有两个视图都可以访问的单例服务。
答案 1 :(得分:0)
存在两个潜在问题:
您可能必须将呼叫延迟到frame.Navigate
,直到应用程序加载完毕。在您的代码示例中,您尝试在将框架分配给Window.Current.Content
之前进行导航。您可以尝试将其移动为lambda块的最后一行。您甚至可能需要同步运行导航,或者至少在UI线程上运行导航。
RunAsync
可能引起问题。您可以使用Dispatcher.Invoke
进行测试,看看它是否仍然存在相同的问题。