Reputation: 837
I am receiving the following exception within a ReactiveUI based ViewModel...
System.NotSupportedException: Unsupported expression of type 'Constant'. Did you miss the member access prefix in the expression?
The error occurs within the constructor of the ValidationEditorDocumentViewModel, within an observable pipeline that is designed to monitor changes on a property (SelectedValidatorClientViewModel) within another Reactive ViewModel (ValidationEditorViewModel).
What I am trying to do is that anytime the ValidationEditorViewModel.SelectedValidatorClientViewModel property were to change, then set the SelectedValidator on another ViewModel (RuleEditorViewModel).
using NextWare.ProductPortalUI.RXViewModels.RXViewModels.ValidationEditor;
using ReactiveUI;
using System;
namespace NextWare.ProductPortalUI.RXViewModels.ValidationEditor
{
public sealed partial class ValidationEditorDocumentViewModel: ReactiveObject
{
private ValidatorEditorViewModel _validationEditorViewModel;
private RuleEditorViewModel _ruleEditorViewModel;
public ValidationEditorDocumentViewModel()
{
var setValidatorRuleSet = this.WhenAnyValue(x => ValidationEditorViewModel.SelectedValidatorClientViewModel)
.Subscribe(_ => SetValidatorOnRuleSet());
}
private void SetValidatorOnRuleSet()
{
if(RuleEditorViewModel != null)
{
RuleEditorViewModel.SelectedValidator = _validationEditorViewModel.SelectedValidatorClientViewModel.Validator;
}
}
public ValidatorEditorViewModel ValidationEditorViewModel
{
get => _validationEditorViewModel;
set => this.RaiseAndSetIfChanged(ref _validationEditorViewModel, value, nameof(ValidationEditorViewModel));
}
}
}
This is the ViewModel that is referenced ...
using NextWare.Domain.ValidationServices.Validator.ClientViewModels;
using NextWare.ProductPortalUI.SharedComponents.DomainMetaExplorer.Models;
using ReactiveUI;
using Splat;
using System;
namespace NextWare.ProductPortalUI.RXViewModels.RXViewModels.ValidationEditor
{
public sealed partial class ValidatorEditorViewModel : ReactiveObject
{
private ValidatorsClientViewModel _validatorsClientViewModel; // Contructor Injected Domain-based ViewModel
private ValidatorClientViewModel _selectedValidatorClientViewModel;
private Guid _selectedDomainElementModelReferenceId = Guid.NewGuid();
private TreeNode _selectedMetaExplorerTreeNode;
public ValidatorEditorViewModel(ValidatorsClientViewModel validatorsClientViewModel = null)
{
_validatorsClientViewModel = validatorsClientViewModel ?? Locator.Current.GetService<ValidatorsClientViewModel>();
this.WhenAnyValue(x => x.SelectedValidatorClientViewModel)
.Subscribe(_ => SetValidator());
this.WhenAnyValue(x => x.SelectedMetaExplorerTreeNode) // Happens only once at startup
.Subscribe(_ => SetValidator());
}
private void SetValidator()
{
if(SelectedValidatorClientViewModel != null && SelectedMetaExplorerTreeNode != null)
{
SelectedValidatorClientViewModel.Validator.DomainElementName = SelectedMetaExplorerTreeNode.ModelMetaData.Name;
SelectedValidatorClientViewModel.Validator.DomainElementNameSpace = SelectedMetaExplorerTreeNode.ModelMetaData.FqViewModelName;
SelectedValidatorClientViewModel.Validator.DomainElementModelReferenceId = SelectedMetaExplorerTreeNode.ModelMetaData.ModelReferenceId;
SelectedValidatorClientViewModel.Validator.AggregateRootModelReferenceId = SelectedMetaExplorerTreeNode.ParentModelMetaData.ModelReferenceId;
}
}
public ValidatorsClientViewModel ValidatorsClientViewModel
{
get => _validatorsClientViewModel;
private set => this.RaiseAndSetIfChanged(ref _validatorsClientViewModel, value, nameof(ValidatorsClientViewModel));
}
public ValidatorClientViewModel SelectedValidatorClientViewModel
{
get => _selectedValidatorClientViewModel;
set => this.RaiseAndSetIfChanged(ref _selectedValidatorClientViewModel, value, nameof(SelectedValidatorClientViewModel));
}
public TreeNode SelectedMetaExplorerTreeNode
{
get => _selectedMetaExplorerTreeNode;
set => this.RaiseAndSetIfChanged(ref _selectedMetaExplorerTreeNode, value, nameof(SelectedMetaExplorerTreeNode));
}
}
}
From documentation, WhenAnyValue extracts the value from IObservableChanged<TSender, TValue> and so as I understand it, there would only be a tick through if ValidationEditorViewModel was not null, no matter if SelectedValidatorClientViewModel were null or not.
I am confused as to why this exception is being thrown.
Upvotes: 2
Views: 2253
Reputation: 2888
As mentioned By Anthony in the comments
Change
var setValidatorRuleSet = this.WhenAnyValue(x => ValidationEditorViewModel.SelectedValidatorClientViewModel)
.Subscribe(_ => SetValidatorOnRuleSet());
to
var setValidatorRuleSet = this.WhenAnyValue(x => x.ValidationEditorViewModel.SelectedValidatorClientViewModel)
.Subscribe(_ => SetValidatorOnRuleSet());
With the additional x
before ValidationEditorViewModel
.
WhenAnyValue relies on you having a lambda from 'x' to your property.
Upvotes: 9