Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AutoRefresh can't work with a data source defined by interface #8

Open
jkears opened this issue Oct 25, 2021 · 3 comments
Open

AutoRefresh can't work with a data source defined by interface #8

jkears opened this issue Oct 25, 2021 · 3 comments

Comments

@jkears
Copy link

jkears commented Oct 25, 2021

I am creating an UI Builder for Blazor and in order to update Blazor when changes occur to the backing ViewModel. In particular, I would like to use the property 'Position' changes within the ComponentViewModel base class. The Position property is updated via a separate Drag/Drop service.

I have an interface for ComponentViewModel called IComponentViewModel which is how I've defined my backing DD SourceList.

private SourceList<IComponentViewModel> _componentViewModelSourceList = new SourceList<IComponentViewModel>();
private ReadOnlyObservableCollection<IComponentViewModel>? _childComponents; 

public CompositeDisposable? Disposables { get; set; }
public IObservable<Position> NewPosition { get; }

Within the constructor I am binding the SourceList to a ReadOnlyObservableCollection 'ChildComponents' as follows, which works great!

            Disposables = new CompositeDisposable();

            Disposables.Add(_componentViewModelSourceList
                .Connect() 
                .ObserveOn(RxApp.MainThreadScheduler) 
                .Bind(out _childComponents)
                .DisposeMany()
                .Subscribe());

Also within the constructor I am attempting to AutoRefresh on changes to the 'Position' property within IComponentViewModel as follows...

var NewPosition = _componentViewModelSourceList.Connect()

             // Subscribe to changes on Position property.
             .AutoRefresh(x => x.Position)
             .Select(); 

however I receive the following error.

CS0311: The type '...IComponentViewModel' cannot be used as a type parameter 'TObject' in the generic method 'IObservableListEx.AutoRefresh<TObject, TProperty> ...'

If I change the SourceList to be the ComponentViewModel then the error goes away, however I would prefer (if possible) to keep it as IComponentViewModel.

Is there some way to add an operator to cast the IObservablable ChangeSet so that I can apply the AutoRefresh with the interface approach.

Thank you in advance.

@RolandPheasant
Copy link
Owner

Do you need to inherit INPC on the interface as well as implementing it on the implementation?

@jkears
Copy link
Author

jkears commented Oct 25, 2021

Hi Roland, a pleasure to make your acquaintance.

Yes, ideally, but so far it may not be needed as in my current design, each specialized ComponentViewModel does not currently have any additional properties that I would need to apply AutoRefresh, but may in the future, so it would be ideal if I could AutoRefresh on any property within either ComponentViewModel as well as any property in the SpecializedComponentViewModel.

At a very high-level, this is the relationship.

Specialized1ComponentViewModel which inherits from ComponentViewModel ==> Binds to Specialized1BlazorViewComponent
..
SpecializedXComponentViewModel which inherits from ComponentViewModel ==> Binds to SpecializedXBlazorViewComponent

The actual Blazor component's Type information is held within the SpecializedComponentViewModel, which is how different components are rendered within the Designer Canvas.

@RolandPheasant
Copy link
Owner

This is really interesting and seems to be the exact opposite of reactivemarbles/DynamicData#512 which for historic reasons has a different behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants