【问题标题】:Keep hitting !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION when I navigate back to a page当我导航回页面时,继续点击!DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
【发布时间】:2018-01-26 07:02:05
【问题描述】:

我正在构建一个 UWP 应用。在我的一个页面上,我一直遇到标题中列出的异常。

这就是场景。应用程序加载。我导航到我的过境页面(导致问题的页面)并且加载正常。然后我很好地导航到另一个页面,但是当我尝试返回 Transit Page 时,我在 App.g.i.cs 文件中遇到了未处理的异常。
异常中的唯一消息是:“参数不正确。\r\n”

我不知道是什么原因造成的。如果我在后面的 Transit 代码中对 OnNavigatedTo 事件的代码进行中断,它会加载 ViewModel,然后我就遇到了错误:

public ICommand TransitButtonCommand
{
    get
    {
        return _TransitButtonCommand ??
            new RelayCommand(() =>
            {
                _navigationService.Navigate(typeof(TransitView));
             });
    }
 }

解决此问题的唯一方法是将: NavigationCacheMode="Required" 在 Transit 视图 XAML 文件中,但这不是最佳选择,因为此页面显示火车/公共汽车时刻表,我需要每次更新它已加载。

有人知道为什么会这样吗?我很乐意提供该项目的更多代码来帮助解决这个问题。

我的 Transit 页面由一个 SplitView 组成,我根据选择的菜单项将另一个 XAML 页面加载到其中。

我创建了一个小项目并把它放在 GitHub 上来演示这个错误,你可以在这里找到它: https://github.com/marekt77/SplitViewBindingTest

运行应用程序,然后导航到 SplitView 页面,然后离开,然后再次返回,您将遇到错误。

【问题讨论】:

  • 这是一个绑定问题。您的 XAML 有问题。你如何设置页面的DataContext
  • Content="{x:Bind myTransitVM.TransitPage, Mode=OneWay}"> ItemsSource="{x:Bind myTransitVM.AvailableTransitInfo, Mode=OneWay}" ItemClick="{x:Bind myTransitVM. TransitOptionsClick}" SelectedIndex="{x:Bind myTransitVM.SelectedIndex, Mode=OneWay}" >
  • ViewModelLocator myVML = new ViewModelLocator(); myTransitVM = myVML.TransitVM; this.DataContext = myTransitVM;

标签: c# uwp uwp-xaml


【解决方案1】:

问题出在SplitViewPageViewModelPanelPage 属性返回 Page。当您第一次导航到 SplitViewPage 时,它会正确地将其绑定到内容,但下一次,您会将其绑定到新的可视化树。 PanelPage 仍然作为您创建的第一个 SplitViewPage 的子对象留在内存中。这将引发异常,因为该页面是另一个元素的子元素。

您需要避免在视图模型中包含任何 UI 元素。他们被困在记忆中。

如果您别无选择,只想让这个东西正常工作,这里有一个解决方法:

public class SplitViewPageViewModel : ViewModelBase
{
    private INavigationService _navigationService;

    public SplitViewPageViewModel(INavigationService navService)
    {
        _navigationService = navService;
        // construction removed here
    }

    private ICommand _OtherPageCommand;
    public ICommand OtherPageCommand
    {
        get
        {
            return _OtherPageCommand ??
                new RelayCommand(() =>
                {
                    _PanelPage = null; // <-- Added this
                    _navigationService.Navigate(typeof(OtherPage));
                });
        }
    }

    private ICommand _HomePageCommand;
    public ICommand HomePageCommand
    {
        get
        {
            return _HomePageCommand ??
                new RelayCommand(() =>
                {
                    _PanelPage = null; // <-- Added this
                    _navigationService.Navigate(typeof(HomePage));
                });
        }
    }

    private Page _PanelPage;
    public Page PanelPage
    {
        get
        {
            // build page on demand
            return _PanelPage ?? (_PanelPage = new Views.PanelPage());
        }
        set
        {
            _PanelPage = value;
            RaisePropertyChanged("PanelPage");
        }
    }
}

现在可以按需创建和处理面板页面。

【讨论】:

  • 谢谢!我一开始确实实现了它,但后来又采用了更多的 MVVM 路线,并在 typeof() 处传递了页面,这也有效,似乎是正确的 MVVM 方法。我的问题是为什么将它作为 typeof() 传递?再次感谢您的帮助!
  • 我认为是因为typeof() 指示UI 实例化什么类型的元素。所以每次绑定时它都会创建一个新的。
猜你喜欢
  • 2019-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多