現状全く使いこなせていないが、とても素晴らしいものだと思う。
さて、この Livet には ViewModelCommand という ICommand の実装があるのだが、どうも使い方を間違っているようで RaiseCanExecuteChanged を呼び出すと NullReferenceException が発生する。
当初、説明書きなぞ一切読まない自分は下記のようなコードを書いていた。
<!-- MainWindow.xaml --> <TextBox HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120" /> <Button Command="{Binding RunCommand}" Content="Run" HorizontalAlignment="Left" Margin="135,9,0,0" VerticalAlignment="Top" Width="75" />
// MainWindowViewModel.cs public MainWindowViewModel() { this.RunCommand = new ViewModelCommand(ExecuteRunCommand, CanExecuteRunCommand); } public ViewModelCommand RunCommand { private set; get; } private void ExecuteRunCommand() { DoSomething(this.Text); } private bool CanExecuteRunCommand() { return !string.IsNullOrEmpty(this.Text); } private string _text; public string Text { set { if(this._text != value) { this._text = value; RaisePropertyChanged(); this.RunCommand.RaiseCanExecuteChanged(); } } get { return this._text; } }このコードでテキストボックスに何か入力すると NullReferenceException が発生する。
ぐぐってもいまいち解決方法がわからない。
仕方がないので GitHub に上がっている Livet の RaiseCanExecuteChanged の実装をのぞきながら確認していく。
するとどうも Livet.DispatcherHelper.UIDispatcher が null なのが原因なようだ。
このキーワードでぐぐるとどうも App.OnStartup 等で下記のような処理を入れなくてはいけないらしい。
protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); Livet.DispatcherHelper.UIDispatcher = this.Dispatcher; }これにより無事 NullReferenceException を回避できた。
知らないとハマる。
GitHub 等で公開されている Livet を使用したアプリを見る限り、当然のように上記の処理が入っているので、常識のようだ。。。