Срабатывает ли ReactiveUI RaiseAndSetIfChanged для List‹T› Add, Delete, Modify?

Будет ли этот огонь

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

Когда я делаю:

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

и т. д.

Я подозреваю, что нет, но не уверен, как мне добиться такого поведения.

У меня есть функция, работающая в фоновом режиме, которая возвращает твиты. Каждый раз, когда я получаю новый твит, я преобразовываю его в TweetTileViewModel и хочу, чтобы он отображался в списке моего пользовательского интерфейса.


person phil    schedule 01.12.2013    source источник


Ответы (1)


Будет ли это огонь?

Нет, это сработает только тогда, когда вы установите список:

TweetTiles = new List<TweetTileViewModel>();

У меня есть функция, работающая в фоновом режиме, которая возвращает твиты. Каждый раз, когда я получаю новый твит, я преобразовываю его в TweetTileViewModel и хочу, чтобы он отображался в списке моего пользовательского интерфейса.

ReactiveUI имеет встроенную поддержку для этого через класс ReactiveList. Вот как вы хотите это настроить — сначала объявите некоторые свойства:

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

ReactiveCommand LoadTweets { get; protected set; }

Затем в конструкторе:

// 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);
});

Обновление: исправлена ​​ошибка типа. Чтобы использовать метод, который отправляет только обратный вызов, используйте 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;
}

Теперь вы можете изменить RegisterAsyncTask только на RegisterAsync, и все готово!

person Ana Betts    schedule 01.12.2013
comment
Вызов Tweets.CreateDerivedCollection дает мне невозможность неявного преобразования в IReactiveDerivedList‹TweetTileViewModel›. Должен ли я использовать другую перегрузку или просто использовать as? Еще одна вещь. API, который я использую для получения твитов, использует обратный вызов, поэтому LoadTweets не возвращается. Есть ли способ сделать Sub вместо обратного вызова? Спасибо - person phil; 02.12.2013
comment
Вау... так близко. Я получаю только 1 обновление в подписке. Единственная разница между моим кодом заключается в том, что возвращается 1 твит вместо списка твитов. Первый твит, который возвращает API, вызывает действие Subscribe onNext, а последующие твиты — нет. StreamTweetsCommand = новая ReactiveCommand(); var newTweets = StreamTweetsCommand.RegisterAsync(p =› twitterApi.GetTweetsObservable(SearchText)); newTweets.Subscribe(x =› { Console.WriteLine(string.Format(Subscribe вызывается для добавления {0}, x)); Tweets.Add(x); }); - person phil; 02.12.2013