Question

What I am doing is this:

Item.PropertyChanged += (sender, args) =>
{
    if(sender is IInterface)
        DoSomethingWith(((IInterface)sender).PropertyFromInterface);
}

how would I go about implementing such a stream in RxUI?

I tried this:

this.WhenAny(x => (x.Item as IInterface).PropertyFromInterface, x.GetValue())
    .Subscribe(DoSomethingWith);

but it seems that is not possible to do.

Would I have to make a property like this? ->

private IInterface ItemAsInterface { get { return Item as IInterface; } }

I made a workaround for now like this:

this.WhenAny(x => x.Item, x => x.GetValue()).OfType<IInterface>()
    .Select(x => x.PropertyFromInterface).DistinctUntilChanged()
    .Subscribe(DoSomethingWith);

but what I actually want is getting the propertychanged updates for "PropertyFromInterface" while Item is of IInterface.

Was it helpful?

Solution 2

Checked back with my old questions, I was looking for something like this solution:

this.WhenAny(x => x.Item, x => x.GetValue()).OfType<IInterface>()
    .Select(x => x.WhenAny(y => y.PropertyFromInterface, y => y.Value).Switch()
    .Subscribe(DoSomethingWith);

The missing link for me was the .Switch method.

Additionally, I wanted the observable to not do anything if the property is NOT of the needed type:

this.WhenAny(x => x.Item, x => x.Value as IInterface)
    .Select(x => x == null ? 
               Observable.Empty : 
               x.WhenAny(y => y.PropertyFromInterface, y => y.Value)
    .Switch().Subscribe(DoSomethingWith);

(e.g. When I set this.Item to an instance of IInterface, I wanted DoSomethingWith to listen to changes to that instance's PropertyFromInterface, and when this.Item gets set to something different, the observable should not continue to fire until this.Item is an instance of IInterface again.)

OTHER TIPS

How about:

this.WhenAny(x => x.Item, x => x.Value as IInterface)
    .Where(x => x != null)
    .Subscribe(DoSomethingWith);

Update: Ok, I vaguely understand what you want to do now - here's how I would do it:

public ViewModelBase()
{
    // Once the object is set up, initialize it if it's an IInterface
    RxApp.MainThreadScheduler.Schedule(() => {
        var someInterface = this as IInterface;
        if (someInterface == null) return;

        DoSomethingWith(someInterface.PropertyFromInterface);
    });
}

If you really want to initialize it via PropertyChanged:

this.Changed
    .Select(x => x.Sender as IInterface)
    .Where(x => x != null)
    .Take(1)   // Unsubs automatically once we've done a thing
    .Subscribe(x => DoSomethingWith(x.PropertyFromInterface));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top