返回上一页时,UWP App随机崩溃

时间:2016-05-27 16:30:42

标签: c# uwp uwp-xaml windows-10-mobile

我有一个应用程序,其中列出了一些项目,然后更改为另一个页面进行编辑。在编辑页面中,我有一些字段,我需要从列表中选择一个值,我在另一个页面中加载。我从编辑页面调用列表页面,从编辑页面视图模型传递一个方法,以便在进行选择时调用,以便我可以更新我的模型和绑定。

问题在于,有时候,当返回到编辑页面时,调试器会在生成的文件App.g.i.cs中打破

 "Error HRESULT E_FAIL has been returned from a call to a COM component." exception. 

它在断开之前完全显示具有正确绑定和选定值的页面。

我通过将其替换为虚拟页面并删除编辑页面设置的任何回调,从值列表的异步加载中排除了可能的错误。错误仍然发生。 编辑页面的导航缓存模式设置为必需,因此我不会丢失以前的更改。我试过没有必要的缓存模式,但仍然出错。

似乎解决这个问题的唯一问题是我从编辑页面xaml中删除了使用自定义转换器的绑定,但我在其他页面中有这些绑定并且从未遇到过问题。(请参阅更新)

生成的代码中的调试器中断:

#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
        UnhandledException += (sender, e) =>
        {
            if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
        };

这是编辑页面的xaml:

<Page.Resources>
    <converters:BooleanToVisibilityConverter x:Key="BoolToVisibility" />
    <converters:StringFormatConverter x:Key="StringFormat" />
    <converters:DateTimeToDateTimeOffsetConverter x:Key="DateOffset" />
    <converters:DateTimeToTimeSpanConverter x:Key="TimeSpan" />
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <fieldSelectControl:BackButtonAndTitle Title="Page Title" />
    <StackPanel Grid.Row="1" Orientation="Horizontal">
        <Button Name="HomeButton"
                Width="70"
                Height="50"
                Background="Black"
                Content="&#xE80F;"
                FontFamily="Segoe MDL2 Assets"
                FontSize="30" />
        <TextBlock Name="PageTitle"
                   FontSize="36"
                   Text="{Binding OrderTitle}" />
    </StackPanel>
    <ProgressRing Grid.Row="2" IsActive="{Binding IsLoading}" />

    <ScrollViewer Grid.Row="2"
                  Height="Auto"
                  HorizontalScrollBarVisibility="Disabled"
                  VerticalScrollBarVisibility="Auto"
                  Visibility="{Binding Path=FinishedLoading,
                                       Converter={StaticResource BoolToVisibility}}">

        <StackPanel Margin="20,10,20,30">
            <TextBlock Margin="0,5,0,5"
                       Style="{StaticResource DetailLabel}"
                       Text="Date" />
            <DatePicker Date="{Binding Day, Mode=TwoWay, Converter={StaticResource DateOffset}}" />
            <TextBlock Margin="0,15,0,5"
                       Style="{StaticResource DetailLabel}"
                       Text="Type" />
            <ComboBox ItemsSource="{Binding ComboValues}" SelectedItem="{Binding SelectedHourType, Mode=TwoWay}" />

            <TextBlock Margin="0,15,0,5"
                       Style="{StaticResource DetailLabel}"
                       Text="Start" />
            <TimePicker ClockIdentifier="24HourClock" Time="{Binding StartTime, Mode=TwoWay, Converter={StaticResource TimeSpan}}" />

            <TextBlock Margin="0,5,0,5"
                       Style="{StaticResource DetailLabel}"
                       Text="End" />
            <TimePicker ClockIdentifier="24HourClock" Time="{Binding EndTime, Mode=TwoWay, Converter={StaticResource TimeSpan}}" />

            <TextBlock Margin="0,15,0,5"
                       Style="{StaticResource DetailLabel}"
                       Text="Amount" />
            <TextBox InputScope="Number" Text="{Binding HValue, Mode=TwoWay}" />



            <fieldSelectControl:FieldWithIconSelector x:Name="fsSelect"
                                                      IconClickedEvent="btnClose_Click"
                                                      IconField="&#xE109;"
                                                      TitleField="Add..."
                                                      TitleIconField=""
                                                      ValueField="" />

            <ScrollViewer Height="Auto"
                          HorizontalScrollBarVisibility="Disabled"
                          VerticalScrollBarVisibility="Auto">
                <ListView x:Name="lstOrders"
                          Height="auto"
                          MaxHeight="600"
                          HorizontalAlignment="Stretch"
                          IsItemClickEnabled="True"
                          ItemClick="lstOrders_ItemClick"
                          ItemsSource="{Binding SelectedEmployees,
                                                Mode=OneWay}">
                    <ListView.ItemTemplate>
                        <DataTemplate x:DataType="data:Responsible">
                            <fieldSelectControl:FieldWithIconSelector x:Name="fsEmployees"
                                                                      IconClickedEvent="fsEmployees_IconClickedEvent"
                                                                      IconField=""
                                                                      TitleField=""
                                                                      TitleIconField=""
                                                                      ValueField="{Binding Name}" />
                        </DataTemplate>
                    </ListView.ItemTemplate>
                    <ListView.ItemContainerStyle>
                        <Style TargetType="ListViewItem">
                            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                        </Style>
                    </ListView.ItemContainerStyle>
                </ListView>
            </ScrollViewer>
            <Button Name="btnSave"
                    Margin="0,20,0,15"
                    HorizontalAlignment="Stretch"
                    Click="btnSave_Click"
                    Visibility="{Binding Path=FinishedSaving,
                                         Converter={StaticResource BoolToVisibility}}">
                <Button.Template>
                    <ControlTemplate>
                        <StackPanel HorizontalAlignment="Stretch"
                                    VerticalAlignment="Stretch"
                                    Background="#0099cc"
                                    Orientation="Vertical"
                                    Padding="5">
                            <TextBlock HorizontalAlignment="Center"
                                       FontFamily="Segoe MDL2 Assets"
                                       FontSize="25"
                                       Text="&#xE74E;" />
                            <TextBlock HorizontalAlignment="Center" Text="Save" />
                        </StackPanel>
                    </ControlTemplate>
                </Button.Template>
            </Button>
        </StackPanel>



    </ScrollViewer>
</Grid>

DateOffset转换器的代码:

public class DateTimeToDateTimeOffsetConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        try
        {
            if (value is DateTime)
            {
                DateTime date = (DateTime)value;
                return new DateTimeOffset(date);
            }
            else
                return new DateTimeOffset(DateTime.Now);
        }
        catch (Exception ex)
        {
            return new DateTimeOffset(DateTime.Now);
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        DateTimeOffset dto = (DateTimeOffset)value;
        return dto.DateTime;
    }
}

TimeOffset转换器的代码:

public class DateTimeToTimeSpanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        try
        {
            if (value is DateTime)
            {
                DateTime date = (DateTime)value;
                return new TimeSpan(date.Ticks);
            }
            else
                return new TimeSpan(DateTime.Now.Ticks);
        }
        catch (Exception ex)
        {
            return new TimeSpan(DateTime.Now.Ticks);
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        TimeSpan ts = (TimeSpan)value;
        DateTime dt = new DateTime(ts.Ticks);

        return dt;
    }
}

鉴于调试器中断的代码,错误似乎是在xaml端,正如我所说,删除日期和时间选择器,这是绑定使用自定义转换器的唯一元素,似乎修复它

我错过了什么?

更新

进一步的测试已经引起我的注意,删除自定义转换器实际上并没有解决问题,它只是增加了导航的数量,直到错误发生。我已经尝试完全删除绑定并仍然出错。除去调用下一页的按钮之外的每个元素似乎都有效,但此时我无法确定它是否确实解决了问题或只是减轻了它。

在旁注中,使用电话Back按钮导航回第一页可以完美无瑕地工作。只有在显式调用Frame.GoBack()时才会出现错误。

2 个答案:

答案 0 :(得分:0)

这些异常并没有提供太多关于导致它们的提示,但有一些事情可以尝试:

  • 我会从ScrollViewer左右移除lstOrders。它没有添加任何值,但它可能会破坏ListView的虚拟化,导致它尝试使用任意数量的内存和CPU,如果您不小心删除了MaxHeight lstOrders }。
  • btnSave模板很糟糕,因为它会删除交互式反馈元素。
  • 确保绑定到的属性不会从UI / Dispatcher线程更改。

答案 1 :(得分:0)

正如对该问题的评论所述,我今天遇到了这个问题。将问题隔离到TimePicker控件是相对简单的,更具体地说,是对控件的Time属性的双向绑定。

然而,要弄清楚它为何发生的原因并不那么直截了当。这似乎是关于可见性的一些问题(我在将应用程序移动到后台时遇到问题)并更新绑定值。无论如何,我尝试了各种各样的事情无济于事。

最后,我尝试将绑定表达式从传统的{Binding}语法更改为已编译的{x:Bind},幸运的是,问题消失了。

也许,试一试,看看它是否解决了你的问题。显然,TimePicker需要位于具有特定数据类型的DataTemplate内,或者 - 在我的情况下 - 具有自定义依赖属性的用户控件。