2017-04-13 22 views
-1

最初は非同期のMVVMパターンがありました。私が解消しました -PropertyChangedEventHandler準備完了

<Grid x:Name="LayoutRoot"> 
    <Button x:Name="button" Content="{Binding Path=bText, FallbackValue=Initial}" Tapped="onTap"/> 
</Grid> 

C#

public partial class VPage : Page 
{ 
    public ViewModel viewModel; 

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

    protected override void OnNavigatedTo(NavigationEventArgs e) { viewModel.onNavigatedTo(); } 
    private void onTap(object sender, TappedRoutedEventArgs eventArgs) { viewModel.onTap(); } 
} 


public class viewModel : INotifyPropertyChanged 
{ 
    private String _bText; 
    public String bText { get { return _bText; } set { _bText = value; DB.major("ViewModel: bText=" + _bText); NotifyPropertyChanged("bText"); } } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged(String info) 
    { 
     if (PropertyChanged == null) 
      writeln("Null handler!"); 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info)); 
    } 

    public void onNavigatedTo() { bText = "Updated via onNavigatedTo"; } 

    private int count = 0; 
    public void onTap() { bText = "Updated via onTap " + count++.ToString(); } 
} 

今全体のコードベースです:

XAML: - 同期 - コードのデバッグに私は次のようにまでなりました、それを取り除いてきましたすべてのモデルと非同期のコードは、デバッグに役立ちます。

開始されると、ページコンストラクタが実行され、完了します。

その後、VPage.OnNavigatedToが呼び出され、ViewModel.onNavigatedTo()が呼び出されます。

OnNavigatedToを呼び出すと、writelnがトリガされ、ハンドラがnullであることを示し、コンポーネントの初期化が何らかの方法で終了していないことを示します。続いて、つまりonTapで、すべて正常に動作し、ハンドラが適切に配置されます。興味深いことに、nullハンドラwritelnがトリガされても、フィールドは "onNavigatedToを介して更新されました"に更新されます。

完全な非同期パターンを実装していたときに、スレッドの問題だと思っていましたが、今ははるかに簡単なことです。

答えて

1

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(); 
} 

UPDATEあなたのページがビジュアルツリーになるまで

バインディングはアクティブになりません。最初に値を取得する場合と取得しない場合がありますが、後で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(); } 
} 
+0

私は2つの場所[OnNavigatedTo()とonComplete()]で試しましたが、喜びはありませんでした。同じ振る舞い。私はyrの診断に同意する。 UIの設定が完了する前に戻ってきます。 – jbhelicon

+0

別の考え方:私はそれが競合状態であるとは確信していません - テキストを取得するモデルのスレッドは、相対的な永遠を取るリモートデータアクセスを行います。何かがどこかでブロックされているようです。 – jbhelicon

+0

あなたのコメントの後にさらにデータを追加する質問を編集しました。あなたのコメントはまだ関連しており、感謝しています。 – jbhelicon

関連する問題