Собственная коллекция с использованием класса кеша - PullRequest
1 голос
/ 10 марта 2010

Я пытаюсь повысить производительность, ограничивая свои объекты в памяти с помощью кэша.

Это создает проблему с моей коллекцией ObservableCollection. Ну, я думаю, что код говорит сам за себя. Я "преобразовал" свою производную ObservableCollection в следующее:

public class TrackCollection : INotifyPropertyChanged, IEnumerable {
    private readonly List<Guid> _guids = new List<Guid>();

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info) {
        if (PropertyChanged != null) {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    public void Add(Track track) {
        _guids.Add(track.Id);
    }

    public void Add(Guid trackId) {
        _guids.Add(trackId);
    }

    public IEnumerator GetEnumerator() {
        var tracks = new List<Track>(_guids.Count);
        foreach(Guid id in _guids)
            tracks.Add(MediaCache.Instance.GetTrack(id));

        return tracks.GetEnumerator();
    }
}

Когда я вызываю Add-методы, я хотел бы вызвать мой NotifyPropertyChanged для самого класса.

У меня такое ощущение, что это неправильный подход к проблеме такого рода, это похоже на обходной путь.

В любом случае, это правильное решение, и если да, то как мне действовать?


Метод кэширования выглядит следующим образом:

    private readonly List<Track> _tracks = new List<Track>();
    public Track GetTrack(Guid id) {
        foreach (var track in _tracks.Where(track => track.Id == id))
            return track;

        _tracks.Add(Database.Database.Instance.GetTrack(id));
        return _tracks[_tracks.Count - 1];
    }

1 Ответ

0 голосов
/ 10 марта 2010

Если вы хотите, чтобы ваша коллекция наблюдалась системой привязки, вам необходимо реализовать INotifyCollectionChanged. Это позволит вам уведомлять заинтересованных клиентов об изменениях в вашей коллекции.

В дополнение к этому, чтобы уведомить слушателей об изменении всего класса, вы можете уведомить об изменении свойства с нулевым значением, переданным для имени. Это заставит все привязки переоценить источник.


Я просмотрел код немного дальше и запутался в твоих намерениях. Каждое перечисление возвращает совершенно новую коллекцию, которая плохо сочетается с понятием наблюдаемой коллекции. Клиенты наблюдаемой коллекции ожидают, что отдельные экземпляры их элементов останутся согласованными, поэтому им нужно только реагировать на реструктуризацию, а не обновлять весь список. Не могли бы вы уточнить, чего вы пытаетесь достичь?


Вместо того, чтобы пытаться обрабатывать ваше кэширование в классе коллекции, возможно, вы можете создать «ссылочный» класс TrackReference и использовать стандартную ObservableCollection. Класс будет выглядеть примерно так:

public class TrackReference
{
    private Guid _id;

    public Track Track
    {
        get { return MediaCache.Instance.GetTrack(id); }
    }

    public TrackReference(Track track)
    {
        _id = track.Id;
    }

    public TrackReference(Guid trackId)
    {
        _id = trackId;
    }
}

Теперь у вас есть облегченная ручка, которую вы можете обойти (и наблюдать в коллекции), которая дает вам доступ к полным данным трека, когда вы будете к этому готовы. Это также хорошее место для добавления любых легких метаданных (возможно, названия дорожки) для ваших классов пользовательского интерфейса в Bind.

...