2016-06-17 12 views
0

MVVMライトViewModelBaseから継承したViewModelのテキスト文字列をXAMLページのMediaElementに話すだけでいいです。ViewModelからXAMLページのMediaElementにストリームを送信するにはどうすればよいですか?

var synthesisStream = await synthesizer.SynthesizeSsmlToStreamAsync(text); 
media.AutoPlay = true; 
media.SetSource(synthesisStream, synthesisStream.ContentType); 
media.Play(); 

上記のコードでは、ViewModelの分離がありません。 mediaはコードビハインドで直接扱われています。

は私のViewModelでは、私は、メッセージのために

var synthesisStream = await synthesizer.SynthesizeSsmlToStreamAsync(text); 

var msg=new PlaySpeechSynthesisStreamMessage(synthesisStream); 
Messenger.Default.Send<PlaySpeechSynthesisStreamMessage>(msg); 

で停止:

public class PlaySpeechSynthesisStreamMessage 
{ 
    public SpeechSynthesisStream Stream { get; set; } 

    public PlaySpeechSynthesisStreamMessage(SpeechSynthesisStream stream) 
    { 
     Stream = stream; 
    } 
} 

Messengerこのような状況を処理するための正しい方法ですか?ストリームをmediaに渡すには、RelayCommandなどを書くにはどうすればよいですか?

関連記事MVVM pattern violation: MediaElement.Play()はこの問題を解決しているようですが、MVVM Lightではなく、ストリームを渡す方法もありません。

答えて

0

このような状況を処理するにはメッセージが良い解決策だと思います。 あなただけのビューでの取り扱いとのViewModelにメッセージの送信を補完する必要があります。

Messenger.Default.Register<PlaySpeechSynthesisStreamMessage>(this, msg => { 
    media.AutoPlay = true; 
    media.SetSource(msg.Stream, msg.Stream.ContentType); 
    media.Play(); 
}); 

また、あなたが引用した問題で説明したイベントのアプローチを使用することができます。この場合、あなたは、次のようにあなたのイベントを定義し、タイプSpeechSynthesisStreamのプロパティでEventArgsから継承するクラスを定義する必要があります:

public event EventHandler<YourEventArgsClass> PlaySpeechSynthesisStreamEvent; 

し、それをこのように上げる:この中

var synthesisStream = await synthesizer.SynthesizeSsmlToStreamAsync(text); 
var eventArgs = new YourEventArgsClass(synthesisStream); 
if (PlaySpeechSynthesisStreamEvent != null) 
    PlaySpeechSynthesisStreamEvent(this, eventArgs); 

をもちろん、ビューでイベントを処理する必要があります。

イベントハンドラを使用するソリューションは、メッセージを持つものよりやや厄介ですが、イベント処理をビューのDataContextに配線する必要があります。また、アプリケーションの構造に応じて、DataContextプロパティViewのライフタイムの始めから常に利用できるとは限りません。たとえば、多くの場合、ビューへのナビゲーション中にNavigation ServiceやBootstrapperを使用して設定する傾向があります。この場合、DataContextはnullです。ビューのコストラクタを使用してイベントハンドラをそこに配線することは不可能です。だから、あなたはそれを配線する別の場所を見つけなければならず、そのようなOnNavigatedFrom(Windows 10 UWPアプリなど)のメソッドをビューのライフサイクルで複数回呼び出すことができ、必ずイベントを配線したくありませんハンドラを複数回使用します。 フレームワークがそれを公開している場合(Windows 10 UWPなど)、DataContextChangedイベントは、ViewModelに関連するイベントハンドラを配線するのに適しています(以前のインスタンスを削除する場合もあります。アプリケーションの存続期間中のViewModelクラスの)。

関連する問題