我们一直在努力让ToProperty正常工作,但遇到了ThrownExceptions未捕获的异常。
我们的测试视图模型如下:
public class ViewModel : ReactiveObject, ISupportsActivation
{
private readonly ViewModelActivator _activator = new ViewModelActivator();
public ViewModelActivator Activator
{
get { return _activator; }
}
private ObservableAsPropertyHelper<String> _output;
public string Output
{
get { return _output.Value; }
}
public ViewModel()
{
this.WhenActivated(delegate(Action<IDisposable> action)
{
action(
Run()
.ToObservable()
.ToProperty(this, vm => vm.Output, out _output, "INIT", RxApp.MainThreadScheduler)
.ThrownExceptions.Subscribe(ex => Debug.WriteLine("Exception {0}", ex.Message)));
});
}
public async Task<string> Run()
{
Debug.WriteLine("Running : Begin");
await Task.Delay(5000);
throw new InvalidOperationException("no way hosay");
Debug.WriteLine("Running : End");
return "Assigned";
}
}
我们的简单视图看起来像
public sealed partial class MainPage : Page,IViewFor<ViewModel>
{
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
this.WhenActivated(d =>
{
d(this.OneWayBind(ViewModel, vm => vm.Output, v => v.Text.Text));
});
}
object IViewFor.ViewModel
{
get { return ViewModel; }
set { ViewModel = (ViewModel)value; }
}
public ViewModel ViewModel
{
get { return (ViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register("ViewModel", typeof(ViewModel), typeof(MainPage), new PropertyMetadata(null));
private void BindButton_OnClick(object sender, RoutedEventArgs e)
{
this.ViewModel = new ViewModel();
}
}
现在,如果他快速连续几次快速点击'BindButton',我们会得到一个未被ThrownExceptions捕获的异常。
为什么会这样?
此外,关于使用ToProperty的指导是什么?
例如,由于_output具有空值,因此在WhenActivated中没有绑定会导致Output属性的get属性中出现异常。鉴于需要长期运行的任务来填充ToProperty值,这是应该遵循的典型结构吗?
编辑:
通过对视图模型进行此更改,我们现在有一种情况,即我们似乎总是捕获异常,为什么会这样?
var exec = Run().ToObservable();
_output = exec.ToProperty(this, x => x.Output, "INIT", RxApp.MainThreadScheduler);
_output.ThrownExceptions.Subscribe(ex => Debug.WriteLine("Exception {0}", ex.Message));
答案 0 :(得分:1)
您看到这些异常的原因是您在ViewModel中使用WhenActivated
,并且在任务完成之前删除了这些VM。除非:
WhenActivated
ListBoxItemViewModel
的{{1}})但说实话,不是每次按下按钮都创建一个新的ViewModel,最好在View的构造函数中创建一个ViewModel,然后将按钮绑定到MessageBus
。