2017-05-11 5 views
2

後、私はそうのようなSystem.Windows.Interactivityを使用してLoadedCommandを結合しています:処分は、実行

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="Loaded"> 
     <i:InvokeCommandAction Command="{Binding LoadedCommand}" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

、ビューがロードされたときに私の見解モデルに私がデータをロードしています:

LoadedCommand = ReactiveCommand.CreateFromTask(LoadData); 

マイ問題は、Loadedイベントが親ビューによって実際に複数回トリガーされることです。 loaddataのメソッドにnullに

async Task LoadData() 
{ 
    if (didLoad) return; 
    ... 
} 

答えて

1

これは、ロードハンドラが複数回呼び出されるため、難しい問題です。気に障る。そこで、これを回避するためのヘルパーコードがいくつかあります。

using System; 
using System.Collections.Generic; 
using System.Reactive.Disposables; 
using System.Reactive.Linq; 
using System.Windows; 

namespace Utils 
{ 
    public static class FrameworkElementExtensions 
    { 
     public static void LoadUnloadHandler 
      (this FrameworkElement control 
      , Func<IDisposable> action) 
     { 
      var state = false; 
      var cleanup = new SerialDisposable(); 
      Observable.Merge 
       (Observable.Return(control.IsLoaded) 
        , control.Events().Loaded.Select(x => true) 
        , control.Events().Unloaded.Select(x => false) 
       ) 
       .Subscribe(isLoadEvent => 
       { 
        if (!state) 
        { 
         // unloaded state 
         if (isLoadEvent) 
         { 
          state = true; 
          cleanup.Disposable = 
           new CompositeDisposable(action()); 
         } 
        } 
        else 
        { 
         // loaded state 
         if (!isLoadEvent) 
         { 
          state = false; 
          cleanup.Disposable = Disposable.Empty; 
         } 
        } 

       }); 
     } 


    } 
} 

コードがロードアンイベントを処理し、複数のコールの問題を除外します。考えられるのは、Loadにコールバックを提供し、アンロードに配置されるIDisposableを返します。

たとえば、ネットワーク接続などの外部リソースに登録する必要がある場合は、コントロールが表示されているときだけ、コードビハインドコンストラクタで行うことができます。

クラス/ライブラリは

を使用しました
+1

私はコードビハインドでコードを書くことを避けようとしていました。もし私がそこに書き込もうとしたら、Observable.FromEventPattern(this、LoadedEvent.Name).Take(1).Subscribe(async _ => ViewModel.LoadData()); 'Take(1)'は私の 'Observable'を処分すべきですか? – DobleA

+1

ロードされたときに一度しか起こらず、あなたの正確な必要性にはおそらくOKであればうまくいくでしょう。私のコードは、実際のロードごとに正しく実行され、ダブルコールをスキップし、アンロード時にすべてのリソースを処分します。私は、特に私がクリーンアップする必要があるコードの背後からグローバルリソースに登録する場合は、常にそれを使用します。 FromEventPatternはむしろFuglyです。私はReactiveUI.Eventsの使用をお勧めしますが、それは味の問題であり、重要ではありません。また、コードの背後を避けてはいけません。 XAMLでいくつかのことをやろうとするのはちょっとした痛みです。 – bradgonesurfing

+0

洞察に感謝します! – DobleA

0

Setコマンド:私のような何かをすることなく、その最初の実行後にLoadedCommandを停止したいと思います。したがって、これのために別のフラグを保持する必要はありません。

async Task LoadData() 
{ 
    // your logic goes here 
    LoadedCommand = null; 
} 
+0

私はそれを試みましたが、 'LoadData'メソッドはまだ呼び出されています。 – DobleA