C# PropertyChangedEventHandler准备好工作了吗

C# PropertyChangedEventHandler准备好工作了吗,c#,wpf,windows,mvvm,C#,Wpf,Windows,Mvvm,我最初有一个异步MVVM模式;在调试过程中,我现在将其简化为以下-synchronous-code: XAML: 这就是现在的全部代码库——我已经删除了所有的模型和异步代码来帮助调试 启动后,页面构造函数将运行并完成 随后,调用VPage.OnNavigatedTo,并调用ViewModel.OnNavigatedTo() 在调用OnNavigatedTo时,writeln将触发,指示处理程序为null,表明组件初始化尚未以某种方式完成。随后-ie onTap-所有工作正常,处理程序已就位。有趣

我最初有一个异步MVVM模式;在调试过程中,我现在将其简化为以下-synchronous-code:

XAML:

这就是现在的全部代码库——我已经删除了所有的模型和异步代码来帮助调试

启动后,页面构造函数将运行并完成

随后,调用VPage.OnNavigatedTo,并调用ViewModel.OnNavigatedTo()

在调用OnNavigatedTo时,writeln将触发,指示处理程序为null,表明组件初始化尚未以某种方式完成。随后-ie onTap-所有工作正常,处理程序已就位。有趣的是,即使触发了null处理程序writeln,字段也会更新为“updated via onNavigatedTo”


当我有了完整的异步模式时,我认为这是一个线程问题,但现在很明显,它要简单得多。

我认为您没有给UI足够的时间来注册它的处理程序。权宜之计是屈服。试试这个:

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    // This forces the rest of your code to enqueue after UI is done.
    await Task.Yield(); 

    viewModel.populate();
}

更新

在页面位于可视树中之前,绑定将不会激活。他们可以先检索值,也可以不检索值,但稍后将订阅
PropertyChanged

如果要确保所有绑定都已就位,则不要订阅
OnNavigatedTo
,而是使用
Loaded

public partial class VPage : Page
{
    public ViewModel viewModel;

    public VPage()
    {
        DataContext = viewModel = new ViewModel();
        InitializeComponent();

        Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        viewModel.onNavigatedTo();
    }

    private void onTap(object sender, TappedRoutedEventArgs eventArgs) { viewModel.onTap(); }
}

感谢您的帮助-我在两个地方尝试了它[OnNavigatedTo()和onComplete()],但没有任何乐趣。同样的行为。我同意你的诊断;我在UI设置完成之前就回来了。另一个想法是:我不相信这是竞争条件——获取文本的模型线程进行远程数据访问,这需要相对较长的时间。某个地方似乎被阻止了。编辑问题以在您的评论后添加更多数据;您的评论仍然是相关的,并表示感谢。您可能需要提供更多帮助。xaml绑定看起来像什么?populate/fillText方法是什么样的?我已经大大简化了代码,消除了所有的模型和异步,从而缩小了审查范围。完整代码现已发布。
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    // This forces the rest of your code to enqueue after UI is done.
    await Task.Yield(); 

    viewModel.populate();
}
public partial class VPage : Page
{
    public ViewModel viewModel;

    public VPage()
    {
        DataContext = viewModel = new ViewModel();
        InitializeComponent();

        Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        viewModel.onNavigatedTo();
    }

    private void onTap(object sender, TappedRoutedEventArgs eventArgs) { viewModel.onTap(); }
}