Modelの処理の一部をViewModelで実施したい。
↓ イメージ。
↑ イメージ。
やりたいこと:
- 再生ボタンは(緑の三角形)は、Model側とバインドしたい。(UI的に)
- 「Playerで再生する」という処理は、ViewModel側で書きたい。(ModelからだとPlayer が遠い…)
とりあえずこうした。
- 前提:ReactiveProperty使ってます。
1. 再生コマンド自体はModel側で作成し、Viewにバインド
XAML: <DataTemplate x:Key="MyTemplate" x:DataType="models:MyModelData"> <Grid> <Button Command="{x:Bind Path=PlayCmd}" CommandParameter="{x:Bind Path=Id}" /> </Grid> </DataTemplate>
Model: public class MyModelData { public Guid Id { get; set; } = Guid.NewGuid(); public string Mp3 { get; set; } // コマンドはここにあるけど、処理はない public ReactiveCommand<Guid> PlayCmd { get; set; } = new ReactiveCommand<Guid>(); public MyModelData(string mp3) { this.Mp3 = mp3; } }
2. 再生コマンドの処理(Subscribe)はViewModel側で書く
ViewModel: public class MainViewModel : Observable { public MyModelData HaruData { get; set; } = new MyModelData("春.mp3")); public MyModelData AkiData { get; set; } = new MyModelData("秋.mp3"); public MainViewModel() { _ = this.HaruData.PlayCmd.Subscribe(x => this.RunAsync(x)); _ = this.AkiData.PlayCmd.Subscribe(x => this.RunAsync(x)); } private async Task RunAsync(Guid x) { if(x == this.HaruData.Id) { // ViewModelからPlayerにアクセスできるようなんとかする(今回省略) Debug.WriteLine("Play " + this.HaruData.Mp3); } if(x == this.AkiData.Id) { Debug.WriteLine("Play " + this.AkiData.Mp3); } return; } }
うーん
もっと・・・こう・・・コレ以外でなんとかできるような。。