現状全く使いこなせていないが、とても素晴らしいものだと思う。
さて、この 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 を使用したアプリを見る限り、当然のように上記の処理が入っているので、常識のようだ。。。
ちょうど同じ問題で詰まっていました。
返信削除Toshi7uさんのおかげで、無事解決しました。
ありがとうございました!!
同じく。。。 はまりました。。。
返信削除お陰様で解決しました。ありがとうございました。