Question

Will this fire

private List<TweetTileViewModel> _TweetTiles;
    public List<TweetTileViewModel> TweetTiles
    {
        get { return _TweetTiles; }
        set { this.RaiseAndSetIfChanged(ref _TweetTiles, value); }
    }

When I do:

TweetTiles.Add(new TweetTileViewModel(...)); or
TweetTiles.Remove(new TweetTileViewModel(...));

etc.

I suspect not, but am not sure how I should get this behavior.

I have a function, running on a background Task, that is returning tweets. Each time I get a new tweet I convert it to a TweetTileViewModel and want it to show in my UI listbox.

Was it helpful?

Solution

Will this fire?

Nope, this will only fire when you set the list:

TweetTiles = new List<TweetTileViewModel>();

I have a function, running on a background Task, that is returning tweets. Each time I get a new tweet I convert it to a TweetTileViewModel and want it to show in my UI listbox.

ReactiveUI has built-in support for this, via the ReactiveList class. Here's how you want to set it up - first, declare some properties:

ReactiveList<Tweet> Tweets { get; protected set; }
IReactiveDerivedList<TweetTileViewModel> TweetViewModels { get; protected set; }

ReactiveCommand LoadTweets { get; protected set; }

Then, in the constructor:

// Note: Only change this list on the UI thread!
Tweets = new ReactiveList<Tweet>();

// Now, TweetViewModels will "follow around" Tweets as you add and remove items
TweetViewModels = Tweets.CreateDerivedCollection(
    tweet => new TweetTileViewModel(tweet));

LoadTweets = new ReactiveCommand();

var newTweets = LoadTweets.RegisterAsyncTask(async _ => {
    // Loads the latest tweets
    return LoadTweetsAsync();
});

newTweets.Subscribe(newTweets => {
    // Add in the new tweets we downloaded. This is guaranteed by
    // ReactiveCommand to be on the UI thread
    Tweets.AddRange(newTweets);
});

Update: Fixed type error. To use a method that only sends a callback, use an AsyncSubject:

public IObservable<List<Tweet>> GetTweetsObservable(this TwitterClient This)
{
    var ret = new AsyncSubject<List<Tweet>>();

    try {
        This.GetTweetsWithCallback(tweets => {
            ret.OnNext(tweets);
            ret.OnCompleted();
        });
    } catch (Exception ex) {
        ret.OnError(ex);
    }

    return ret;
}

Now, you can change RegisterAsyncTask to just RegisterAsync and you're good to go!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top