using MediaBrowser.Model.Dto; using System; using System.Threading; using System.Windows; namespace MediaBrowser.UI.ViewModels { /// /// Represents a view model that contains multiple items. /// This should be used if you want to display a button or list item that holds more than one item, /// and cycle through them periodically. /// public class ItemCollectionViewModel : BaseViewModel, IDisposable { private int RotationPeriodMs { get; set; } public ItemCollectionViewModel(int rotationPeriodMs = 10000, int rotationDevaiationMs = 2000) : base() { if (rotationDevaiationMs > 0) { rotationPeriodMs += new Random(Guid.NewGuid().GetHashCode()).Next(0 - rotationDevaiationMs, rotationDevaiationMs); } RotationPeriodMs = rotationPeriodMs; } /// /// Gets the timer that updates the current item /// private Timer CurrentItemTimer { get; set; } private string _name; /// /// Gets or sets the name of the collection /// public string Name { get { return _name; } set { _name = value; OnPropertyChanged("Name"); } } private BaseItemDto[] _items; /// /// Gets or sets the list of items /// public BaseItemDto[] Items { get { return _items; } set { _items = value ?? new BaseItemDto[] { }; OnPropertyChanged("Items"); CurrentItemIndex = Items.Length == 0 ? -1 : 0; ReloadTimer(); } } private int _currentItemIndex; /// /// Gets or sets the index of the current item /// public int CurrentItemIndex { get { return _currentItemIndex; } set { _currentItemIndex = value; OnPropertyChanged("CurrentItemIndex"); OnPropertyChanged("CurrentItem"); OnPropertyChanged("NextItem"); } } /// /// Gets the current item /// public BaseItemDto CurrentItem { get { return CurrentItemIndex == -1 ? null : Items[CurrentItemIndex]; } } /// /// Gets the next item /// public BaseItemDto NextItem { get { if (CurrentItem == null || CurrentItemIndex == -1) { return null; } var index = CurrentItemIndex + 1; if (index >= Items.Length) { index = 0; } return Items[index]; } } /// /// Disposes the timer /// private void DisposeTimer() { if (CurrentItemTimer != null) { CurrentItemTimer.Dispose(); } } /// /// Reloads the timer /// private void ReloadTimer() { DisposeTimer(); // Don't bother unless there's at least two items if (Items.Length > 1) { CurrentItemTimer = new Timer(state => Application.Current.Dispatcher.InvokeAsync(IncrementCurrentItemIndex), null, RotationPeriodMs, RotationPeriodMs); } } /// /// Increments current item index, or resets it back to zero if we're at the end of the list /// private void IncrementCurrentItemIndex() { var newIndex = CurrentItemIndex + 1; if (newIndex >= Items.Length) { newIndex = 0; } CurrentItemIndex = newIndex; } /// /// Disposes the collection /// public void Dispose() { DisposeTimer(); } } }